当列名在其他地方预定义时,R data.table在条件子集设置方面举步维艰



假设我有一个数据表

library(data.table)
DT <- data.table(x=c(1,1,0,0),y=c(0,1,2,3))
column_name <- "x"
x y
1: 1 0
2: 1 1
3: 0 2
4: 0 3

我想访问x=1的所有行,但要使用column_name。

所需的输出应该如下所示:

DT[x==1,]
x y
1: 1 0
2: 1 1

但是在输入中CCD_ 1被CCD_。

请注意,这个问题与data.table R中的Select列子集类似,但不完全相同,并且那里的解决方案(使用=FALSE(在这里不起作用

以下是我尝试过的所有东西。它们都不起作用。

DT[column_name ==1,]
DT[.column_name ==1,]
DT[.(column_name) ==1,]
DT[..column_name ==1,]
DT[."column_name" ==1,]
DT[,column_name ==1,]
DT[,column_name ==1,with=TRUE]
DT[,column_name ==1,with=FALSE]
DT[,.column_name ==1,with=TRUE]
DT[,.column_name ==1,with=FALSE]
DT[,..column_name ==1,with=TRUE]
DT[,..column_name ==1,with=FALSE]
DT[,."column_name" ==1,with=TRUE]
DT[,.column_name ==1,with=FALSE]
DT[column_name ==1,with=TRUE]
DT[column_name ==1,with=FALSE]
DT[[column_name==1,]]
subset(DT,column_name==1)

我还启用了options(datatable.WhenJisSymbolThenCallingScope=TRUE)

很明显,我缺少某种词汇技巧。我花了几个小时浏览小插曲和SO问题,但都无济于事。

我可以想象这对你来说是非常令人沮丧的。我对你在发帖前尝试的内容数量表示赞赏。这里有一种方法:

DT[get(column_name) == 1,]
x y
1: 1 0
2: 1 1

如果需要在J中使用column_name,可以使用get(..column_name):

DT[,get(..column_name)]
[1] 1 1 0 0

..指示在父环境中进行评估。

IJ中使用字符串的另一种方法是使用x0:

DT[eval(as.name(column_name)) == 1]
x y
1: 1 0
2: 1 1
DT[,eval(as.name(column_name))]
[1] 1 1 0 0

您可以按名称对列进行子集设置,然后选择行。

library(data.table)
DT[DT[[column_name]] == 1]
#   x y
#1: 1 0
#2: 1 1

需要注意的是,直接将get()paste0()一起使用是不可行的。您必须首先将粘贴分配给一个变量,如:

# Doesn't work:
dt[get(paste0(column_name, 'some_string')) == 1]
# Does work:
this_col_name = paste0(column_name, 'some_string')
dt[get(this_col_name) == 1]

我刚刚发现的另一个答案是:如果有多个以这种方式命名的列,并且您希望返回所有列,请不要使用get,而是使用mget

示例:

df <- data.table(x=1:4,y=1:4,z=1:4,w=1:4)    # here's my data table
desired_columns <- c("y","z","w")            # I want to return only columns Y, Z and W

如果我尝试:

> df[,get(desired_columns)]
Error in get(desired_columns) : first argument has length > 1

相反:

> df[,mget(desired_columns)]
y z w
1: 1 1 1
2: 2 2 2
3: 3 3 3
4: 4 4 4

最新更新