data.table中的逻辑运算符与by-groups

时间:2016-11-03 18:35:02

标签: r data.table

我正在尝试将逻辑运算符应用于data.table的列,它可以在没有= groups的情况下正常工作,但是使用by = groups会发生奇怪的事情。我正在使用R 3.3.1和data.table 1.9.6(关闭CRAN)。

以下是一个示例数据集:

library(data.table)
# x <- matrix(rnorm(10),ncol=2)
x <- structure(c(0.323618333400921, -0.103619160085676, -0.823322722581548, 
-0.0175726272468397, 2.17286179204364, 1.63465793636681, 0.258469984285221, 
-0.411622451584, 0.22594247704226, 0.114427086028551), .Dim = c(5L, 2L))

dt <- data.table(x)
dt$id <- c(1,1,1,2,2)
dt

##             V1         V2 id
## 1:  0.32361833  1.6346579  1
## 2: -0.10361916  0.2584700  1
## 3: -0.82332272 -0.4116225  1
## 4: -0.01757263  0.2259425  2
## 5:  2.17286179  0.1144271  2

假设我想知道累积最小值(即从样本开始到当前行,或从by = group开始到当前行的每列中的最小值)是否低于零。当没有by = groups时,我们很好:

dt[, cummin(.SD), .SDcols=1:2]
##            V1         V2
## 1:  0.3236183  1.6346579
## 2: -0.1036192  0.2584700
## 3: -0.8233227 -0.4116225
## 4: -0.8233227 -0.4116225
## 5: -0.8233227 -0.4116225

> dt[, cummin(.SD)<0, .SDcols=1:2]
##         V1    V2
## [1,] FALSE FALSE
## [2,]  TRUE FALSE
## [3,]  TRUE  TRUE
## [4,]  TRUE  TRUE
## [5,]  TRUE  TRUE

到目前为止一切顺利。我还可以用by = groups计算实际累积最小值:

dt[, cummin(.SD), by=id]
##    id          V1         V2
## 1:  1  0.32361833  1.6346579
## 2:  1 -0.10361916  0.2584700
## 3:  1 -0.82332272 -0.4116225
## 4:  2 -0.01757263  0.2259425
## 5:  2 -0.01757263  0.1144271

但是,如果我尝试像以前一样计算指标变量,则输出如下:

dt[, (cummin(.SD)<0), by=id]
##     id    V1
##  1:  1 FALSE
##  2:  1  TRUE
##  3:  1  TRUE
##  4:  1 FALSE
##  5:  1 FALSE
##  6:  1  TRUE
##  7:  2  TRUE
##  8:  2  TRUE
##  9:  2 FALSE
## 10:  2 FALSE

而不是5个障碍的2个变量。每个,我们有一个10。看起来在每个副组中,变量堆叠在彼此之上。我该如何正确地做到这一点?

2 个答案:

答案 0 :(得分:3)

它适用于lapply

dt[,lapply(.SD,function(x) cummin(x)<0),by="id"]
   id    V1    V2
1:  1 FALSE FALSE
2:  1  TRUE FALSE
3:  1  TRUE  TRUE
4:  2  TRUE FALSE
5:  2  TRUE FALSE

正如David Arenburg评论的那样,似乎它与cummin(.SD)一起使用,因为它是一个data.frame,它不能与cummin(.SD)<0一起使用,这是一个矩阵。所以另一个解决方案是将矩阵转换为data.frame:

dt[, (as.data.frame(cummin(.SD)<0)), by=id]
   id    V1    V2
1:  1 FALSE FALSE
2:  1  TRUE FALSE
3:  1  TRUE  TRUE
4:  2  TRUE FALSE
5:  2  TRUE FALSE

答案 1 :(得分:1)

您可以尝试这样的事情:

dt2 <- dt[, cummin(.SD), by = id]
results <- data.table(dt2[, .SD<0])
results$id <- dt$id

results
   id    V1    V2
1:  1 FALSE FALSE
2:  1  TRUE FALSE
3:  1  TRUE  TRUE
4:  2  TRUE FALSE
5:  2  TRUE FALSE