在数据表的多个列上进行子集和分配

时间:2014-06-19 01:58:58

标签: r data.table

假设我有一个如下所示的数据表:

library(data.table)
N = 10
x = data.table(id = 1:N, 
               segm = sample(c("A","B","C"),N,replace=T), r = rnorm(N,20,5),
               aa = sample(0:1,N,replace=T), ab = sample(0:1,N,replace=T), 
               ba = sample(0:1,N,replace=T), bb = sample(0:1,N,replace=T))

我想知道如何替换NA的1个值,但仅限于列aaabba和{{1}使用数据表包。我知道如何使用数据框执行此操作。

我尝试使用以下内容:

bb

但我收到了错误:f = c("aa","ab","ba","bb") x[,f,with=F][x[,f,with=F]==1] <- "NA"

总而言之,我的问题是:如何在数据表的多个列上同时进行子集和分配。

代码行:

Error in [<-.data.table(*tmp*, , f, with = F, value = list(aa = c("0",  : unused argument (with = F)

只是不起作用。为什么呢?

任何帮助都表示赞赏。

2 个答案:

答案 0 :(得分:4)

对于这种特殊情况,可以通过另一种方式实现这一目标:

x[, (f) := lapply(.SD, function(x) x * (x | NA)), .SDcols=f]

我们在此使用TRUE | NA = TRUEFALSE | NA = NA这一事实。 (的LHS中的:=将其视为表达式(而不是变量名称),因此对其进行求值以获取其中包含的列。指定.SDcols只为.SD提供f,我们想要的是什么。我们通过引用来应用函数的这个hack来替换每一列。


DT[f == 1, f := NA]

不起作用,因为:

让我们将您的表达式写为DT[i, LHS := RHS]。作为表达式的iDT的范围内进行评估。 [.data.table尝试在f范围内找到列DT,因为没有任何内容,它会尝试在调用范围内找到并获取值存储在其中,然后变为:c("aa", "ab", "ba", "bb") == 1。此评估结果为FALSE, FALSE, FALSE, FALSE,结果为空data.table - j中的作业无效。

另请注意我的答案中(中的LHS。这样我们仍然可以方便地使用DT[, f := val] f 列名称。{/ p>

答案 1 :(得分:3)

在这里使用for()循环没有任何问题。

鉴于您的问题的性质,在四列中的每一列中操作不同的行子集,您将需要使用某些类型的循环;您也可以构建一个明确的版本,以便您充分利用 data.table 的修改引用:=运算符。

for (i in f)
    x[get(i)==1, (i):=NA]

x
#     id segm         r aa ab ba bb
#  1:  1    C 15.203246 NA NA  0  0
#  2:  2    B 23.536583 NA  0  0 NA
#  3:  3    A 16.404203 NA  0 NA  0
#  4:  4    A 18.673618  0  0 NA NA
#  5:  5    C 30.528967 NA  0 NA NA
#  6:  6    A 18.887781  0 NA NA NA
#  7:  7    C 24.476124  0  0 NA NA
#  8:  8    B 26.862686  0  0 NA  0
#  9:  9    C  9.047837  0  0  0 NA
# 10: 10    C 17.532379  0  0 NA NA