迭代减去数据框中的向量
Iteratively subtract vectors in dataframe
还有很多类似的问题,但我非常有信心这个问题是独一无二的。
我有一个大型数据框,其中包含包含数字向量和各种 ID 的变量。
> dataframe
ID ID.2 vectors
1 a c(6, 3, 7, 4, 7, 2, 6)
1 a c(4, 7, 2, 7, 4, 7, 8)
2 a c(5, 8, 2, 7, 8, 9, 9)
2 a c(6, 9, 7, 2, 6, 8, 9)
1 b c(4, 8, 2, 6, 8, 9, 0)
1 b c(5, 8, 2, 7, 8, 9, 9)
我需要遍历数据帧并通过 ID 变量找到向量之间的差异。所以上面假数据的输出应该是这样的:
> dataframe$difference
c(2, -4, 5, -3, 3, -5, -2)
NA # because difference has been found
c(-1, -1, -4, 5, 2, 1, 0)
NA
c(-1, 0, 0, -1, 0, 0, -9)
NA
要弄清楚这一点(令人惊讶地)很复杂。提前致谢。
如果是针对单个数字,您可以使用 diff
,但对于向量的列表列(大概),您需要退回到列表操作,例如 purrr::accumulate
(对于连续减法)或 purrr::map2
(成对)。 dplyr::lead
将向上移动一位并插入 NA
s.
library(tidyverse)
df <- data_frame(ID = c(1L, 1L, 2L, 2L, 1L, 1L),
ID.2 = c("a", "a", "a", "a", "b", "b"),
vectors = list(c(6, 3, 7, 4, 7, 2, 6), c(4, 7, 2, 7, 4, 7, 8), c(5, 8, 2, 7, 8, 9, 9), c(6, 9, 7, 2, 6, 8, 9), c(4, 8, 2, 6, 8, 9, 0), c(5, 8, 2, 7, 8, 9, 9)))
df %>%
group_by(ID, ID.2) %>%
mutate(diff = map2(vectors, lead(vectors), `-`)) %>%
as.data.frame() # for printing
#> ID ID.2 vectors diff
#> 1 1 a 6, 3, 7, 4, 7, 2, 6 2, -4, 5, -3, 3, -5, -2
#> 2 1 a 4, 7, 2, 7, 4, 7, 8 NA, NA, NA, NA, NA, NA, NA
#> 3 2 a 5, 8, 2, 7, 8, 9, 9 -1, -1, -5, 5, 2, 1, 0
#> 4 2 a 6, 9, 7, 2, 6, 8, 9 NA, NA, NA, NA, NA, NA, NA
#> 5 1 b 4, 8, 2, 6, 8, 9, 0 -1, 0, 0, -1, 0, 0, -9
#> 6 1 b 5, 8, 2, 7, 8, 9, 9 NA, NA, NA, NA, NA, NA, NA
还有很多类似的问题,但我非常有信心这个问题是独一无二的。
我有一个大型数据框,其中包含包含数字向量和各种 ID 的变量。
> dataframe
ID ID.2 vectors
1 a c(6, 3, 7, 4, 7, 2, 6)
1 a c(4, 7, 2, 7, 4, 7, 8)
2 a c(5, 8, 2, 7, 8, 9, 9)
2 a c(6, 9, 7, 2, 6, 8, 9)
1 b c(4, 8, 2, 6, 8, 9, 0)
1 b c(5, 8, 2, 7, 8, 9, 9)
我需要遍历数据帧并通过 ID 变量找到向量之间的差异。所以上面假数据的输出应该是这样的:
> dataframe$difference
c(2, -4, 5, -3, 3, -5, -2)
NA # because difference has been found
c(-1, -1, -4, 5, 2, 1, 0)
NA
c(-1, 0, 0, -1, 0, 0, -9)
NA
要弄清楚这一点(令人惊讶地)很复杂。提前致谢。
如果是针对单个数字,您可以使用 diff
,但对于向量的列表列(大概),您需要退回到列表操作,例如 purrr::accumulate
(对于连续减法)或 purrr::map2
(成对)。 dplyr::lead
将向上移动一位并插入 NA
s.
library(tidyverse)
df <- data_frame(ID = c(1L, 1L, 2L, 2L, 1L, 1L),
ID.2 = c("a", "a", "a", "a", "b", "b"),
vectors = list(c(6, 3, 7, 4, 7, 2, 6), c(4, 7, 2, 7, 4, 7, 8), c(5, 8, 2, 7, 8, 9, 9), c(6, 9, 7, 2, 6, 8, 9), c(4, 8, 2, 6, 8, 9, 0), c(5, 8, 2, 7, 8, 9, 9)))
df %>%
group_by(ID, ID.2) %>%
mutate(diff = map2(vectors, lead(vectors), `-`)) %>%
as.data.frame() # for printing
#> ID ID.2 vectors diff
#> 1 1 a 6, 3, 7, 4, 7, 2, 6 2, -4, 5, -3, 3, -5, -2
#> 2 1 a 4, 7, 2, 7, 4, 7, 8 NA, NA, NA, NA, NA, NA, NA
#> 3 2 a 5, 8, 2, 7, 8, 9, 9 -1, -1, -5, 5, 2, 1, 0
#> 4 2 a 6, 9, 7, 2, 6, 8, 9 NA, NA, NA, NA, NA, NA, NA
#> 5 1 b 4, 8, 2, 6, 8, 9, 0 -1, 0, 0, -1, 0, 0, -9
#> 6 1 b 5, 8, 2, 7, 8, 9, 9 NA, NA, NA, NA, NA, NA, NA