重新组合数据集

时间:2017-03-10 13:38:51

标签: r dplyr tidyr

使用以下数据集:

  id from to trip
1  1    A  B <NA>
2  1    B  C    X
3  1    C  D <NA>
4  1    D  A    X
5  2    B  A    X
6  2    A  C <NA>
7  2    C  D <NA>

每当我在旅程列上找到X时,我都会尝试拆分数据,以获得类似的结果(注意有一个新列):

  id from to trip group
1  1    A  B <NA>  1
2  1    B  C    X  1
3  1    C  D <NA>  2
4  1    D  A    X  2
5  2    B  A    X  3
6  2    A  C <NA>  4
7  2    C  D <NA>  4

这意味着它通过观察/行,并且基于id和trip列,每次到达X时都会启动一个新的数字。

我已经尝试了group_by(df, id, trip)的一些事情,但我总是没有与那个结构类似的结构。

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

此基本R方法适用于示例:

df$group <- c(1, head(cumsum(df$trip == "X") + 1, -1))

在示例中,它返回

df
  id from to trip group
1  1    A  B <NA>     1
2  1    B  C    X     1
3  1    C  D <NA>     2
4  1    D  A    X     2
5  2    B  A    X     3
6  2    A  C <NA>     4
7  2    C  D <NA>     4

另外,在第一次观察是“X”的情况下,那么1将是第一个元素,2将是第二个元素,我认为这是期望的。

正如@manotheshark在提交中提到的,此解决方案不适用于NA值,因为cumsum将在遇到第一个NA后返回NA。建议的解决方案是将df$trip == "X"替换为is.na(df$trip),这将在存在NA的情况下返回正确的值。

答案 1 :(得分:0)

试试这个(如果你真的需要在行之后开始新组 X我认为你可以通过另一个shift()来实现这一点==“X”:

library(data.table)
set.seed(1)

na.zero <- function (x) {
  x[is.na(x)] <- 0
  return(x)
}

dt <- data.table(id = c(1,1,1,2,2,2),
                 from = sample(c("A", "B", "C", "D"), 6, replace = T),
                 to = sample(c("A", "B", "C", "D"), 6, replace = T),
                 trip = sample(c("X", NA), 6, replace = T))

dt[, group:=(cumsum(na.zero(trip=="X"))+cumsum(id-na.zero(shift(id, 1L,type = 'lag'))))]

   id from to trip group
1:  1    B  D   NA     1
2:  1    B  C    X     2
3:  1    C  C   NA     2
4:  2    D  A    X     4
5:  2    A  A   NA     4
6:  2    D  A   NA     4