我有一个数据表“dt”,如下所示:
a b1 b2 b3 b4 t t1
1: 1 4 1 9 NA FALSE TRUE
2: 2 5 1 9 2 FALSE TRUE
3: 3 6 1 9 NA FALSE FALSE
library(data.table)
dt = setDT(structure(list(a = 1:3, b1 = 4:6, b2 = c(1L, 1L, 1L), b3 = c(9L,
9L, 9L), b4 = c(NA, 2L, NA), t = c(FALSE, FALSE, FALSE), t1 = c(TRUE,
TRUE, FALSE)), .Names = c("a", "b1", "b2", "b3", "b4", "t", "t1"
), row.names = c(NA, -3L), class = "data.frame"))
我想创建列t1,如果逐行“a”的值在任何“b”列中,则为true,如:
dt[,t1 := a %in% c(b1,b2,b3,b4)]
但是,我在函数中使用此代码,b列的数量可能会有所不同,所以我想动态地引用它们。
我尝试过这样的事情:
dt[,t := a %in% paste0("b" 1:4)]
但它在字符串“b1”,“b2”,“b3”或“b4”中查找a的值并返回FALSE。有没有办法在j?
中动态引用数据表的列答案 0 :(得分:1)
这就是你想要的。它使用grepl
函数来获取列名在其第一个字符中具有b
的列号。然后使用这些列索引来测试a
列值是否等于b
列中的任何列值。
对该比较的布尔结果求和(避免NA
值)并测试总和> 0(告诉我们至少有一个值为TRUE)并将这些值分配给t1
列。
这也有一个优点(如果是一个),b
列不必是连续的。
bcols = which(grepl('^b', names(dt)))
dt$t1 = apply((dt$a == dt[,bcols]), 1, sum, na.rm=T) > 0
答案 1 :(得分:1)
此处尝试使用.SDcols
指定b1:bn
列,然后将其值与a
列中的值进行比较:
dt[, Reduce(`+`, lapply(.SD, function(x) x==a & (!is.na(x)) )) > 0, .SDcols=b1:b4]
#[1] TRUE TRUE FALSE
dt
的位置:
dt <- data.table(a = 1:3, b1 = 4:6, b2 = c(1L, 1L, 1L), b3 = c(9L,
9L, 9L), b4 = c(NA, 2L, NA), t = c(FALSE, FALSE, FALSE), t1 = c(TRUE,
TRUE, FALSE))