Data.table:基于给定列或另一列的“组计数器”

时间:2016-07-26 17:21:50

标签: r data.table

我有(c.LastName + ' ' + c.Firstname) = ( CASE @PatientName WHEN '' THEN (c.LastName + ' ' + c.Firstname) ELSE '%' + @PatientName + '%' END )

data.table

我想基于列“x”或列“y”创建一个“组计数器”列。我测试过:> DT <- data.table(x = c(15,48,NA,NA,NA,45,45,45,45,75,75,75,NA,2,3,1), y = c(74,159,120,120,120,14,14,14,14,12,23,23,8,8,8,8)) > DT x y 1: 15 74 2: 48 159 3: NA 120 4: NA 120 5: NA 120 6: 45 14 7: 45 14 8: 45 14 9: 45 14 10: 75 12 11: 75 23 12: 75 23 13: NA 8 14: 2 8 15: 3 8 16: 1 8 。但是,我没有得到必须的结果:

DT[ , Index := .GRP, by = c("x","y") ]

1 个答案:

答案 0 :(得分:3)

以下是在某些条件下使用cumsum的方法:

DT[, cumsum(c(1, tail(pmin(x!=shift(x), y!=shift(y),na.rm=TRUE), -1)))]
[1] 1 2 3 3 3 4 4 4 4 5 5 5 6 6 6 6

x != shift(x)比较列中的相邻元素(与y相同)并返回逻辑。 pmin函数比较逻辑比较的结果并选择每个元素的最小值,即如果任一向量具有未改变的元素,则观察被标记为不改变。 tail函数会删除初始NA,cumsum函数会将结果合并到所需的矢量中。

请注意,此方法将产生NAs,其中x和y的观察值都具有NA。在使用cumsum之前,您可以在另外的步骤中解决此问题。

这将适用于字符变量:

# same data.table with character variables
DT <- data.table(x = as.character(c(15,48,NA,NA,NA,45,45,45,45,75,75,75,NA,2,3,1)),
                 y = as.character(c(74,159,120,120,120,14,14,14,14,12,23,23,8,8,8,8)))

DT[, cumsum(c(1, tail(pmin(x!=shift(x), y!=shift(y),na.rm=TRUE), -1)))]
 [1] 1 2 3 3 3 4 4 4 4 5 5 5 6 6 6 6

请注意,与data.frame不同,data.table不会将字符变量转换为因子:

str(DT)
Classes ‘data.table’ and 'data.frame':  16 obs. of  2 variables:
 $ x: chr  "15" "48" NA NA ...
 $ y: chr  "74" "159" "120" "120" ...
 - attr(*, ".internal.selfref")=<externalptr>