添加一个data.table列,告诉C其他C列之一是否包含某个值

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (14)

假设我有一个data.tableC列在N个可能的值中保存离散值:

set.seed(123)
datapoints = data.table(replicate(3, sample(0:5, 4, rep=TRUE)))
print(datapoints)
   V1 V2 V3
1:  1  5  3
2:  4  0  2
3:  2  3  5
4:  5  5  2

(这里C = 3,N = 5)

我想添加N列,如果C列中包含第N个值则返回TRUE,否则FALSE:

   V1 V2 V3  has0  has1  has2  has3  has4  has5
1:  1  5  3 FALSE  TRUE FALSE  TRUE FALSE  TRUE
2:  4  0  2  TRUE FALSE  TRUE FALSE  TRUE FALSE
3:  2  3  5 FALSE FALSE  TRUE  TRUE FALSE  TRUE
4:  5  5  2 FALSE FALSE  TRUE FALSE FALSE  TRUE

我试过这个:

for (value in 0:5) {
  datapoints <- datapoints[, (paste("has", value, sep="")) := (value %in% .SD), .SDcols = c("V1", "V2", "V3")]
}

列已添加但返回FALSE

   V1 V2 V3  has0  has1  has2  has3  has4  has5
1:  1  5  3 FALSE FALSE FALSE FALSE FALSE FALSE
2:  4  0  2 FALSE FALSE FALSE FALSE FALSE FALSE
3:  2  3  5 FALSE FALSE FALSE FALSE FALSE FALSE
4:  5  5  2 FALSE FALSE FALSE FALSE FALSE FALSE

在我看来,如果我替换.SD为对当前行(而不是整个表)的引用,代码将起作用,但我不知道该怎么做。

添加这些列的有效方法是什么?

提问于
用户回答回答于

这是一种方式

library(data.table)

# sample data
set.seed(123)
datapoints = data.table(replicate(3, sample(0:5, 4, rep=TRUE)))

# find if value exists
for(value in 0:5) {
  datapoints[, paste("has", value, sep="") := apply(.SD, 1, function(x) any(x %in% value)), .SDcols = c("V1", "V2", "V3")]
}

datapoints
#>    V1 V2 V3  has0  has1  has2  has3  has4  has5
#> 1:  1  5  3 FALSE  TRUE FALSE  TRUE FALSE  TRUE
#> 2:  4  0  2  TRUE FALSE  TRUE FALSE  TRUE FALSE
#> 3:  2  3  5 FALSE FALSE  TRUE  TRUE FALSE  TRUE
#> 4:  5  5  2 FALSE FALSE  TRUE FALSE FALSE  TRUE

为了更加灵活,您还可以更换any(x %in% value)sum(x %in% value)获得该值每行出现了多少次。对于同样的例子

# find how many times a value exists
for(value in 0:5) {
  datapoints[, paste("has", value, sep="") := apply(.SD, 1, function(x) sum(x %in% value)), .SDcols = c("V1", "V2", "V3")]
}

datapoints
#>    V1 V2 V3 has0 has1 has2 has3 has4 has5
#> 1:  1  5  3    0    1    0    1    0    1
#> 2:  4  0  2    1    0    1    0    1    0
#> 3:  2  3  5    0    0    1    1    0    1
#> 4:  5  5  2    0    0    1    0    0    2

当然,如果您只想要一个列的子集,您仍然可以使用.SDcols。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励