将一列数据表的值与同一表中的动态列数进行比较

时间:2017-01-05 21:57:01

标签: r data.table

我有一个数据表“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?

中动态引用数据表的列

2 个答案:

答案 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))