我试图以类似的方式操作一些data.tables,并希望编写一个函数来完成此任务。我想传入一个参数,其中包含将执行操作的列列表。当列的向量声明是:=运算符的左侧时,这可以正常工作,但如果先前声明(或传递给函数)则不行。以下代码显示了问题。
dt = data.table(a = letters, b = 1:2, c=1:13)
colsToDelete = c('b', 'c')
dt[,colsToDelete := NULL] # doesn't work but I don't understand why not.
dt[,c('b', 'c') := NULL] # works fine, but doesn't allow passing in of columns
错误是"添加新列' colsToDelete'然后分配NULL(删除它)。"很明显,它的解释' colsToDelete'作为新的列名。
沿着这些行做某事时会出现同样的问题
dt[, colNames := lapply(.SD, adjustValue, y=factor), .SDcols = colNames]
我是R的新手,但对其他语言更有经验,所以这可能是一个愚蠢的问题。
答案 0 :(得分:42)
这主要是因为我们允许:=
的LHS上的符号添加新列,以方便:ex:DT[, col := val]
。因此,为了区分col
本身是名称与col
中存储的列名称,我们检查LHS是name
还是expression
。
如果它是name
,它会在LHS上添加名称相同的列,如果expression
,则会对其进行评估。
DT[, col := val] # col is the column name.
DT[, (col) := val] # col gets evaluated and replaced with its value
DT[, c(col) := val] # same as above
首选的习语是:dt[, (colsToDelete) := NULL]
HTH
答案 1 :(得分:4)
要扩展上一个答案,您可以通过以下方式删除列:
# delete columns 10 to 15
dt[ , (10:15) := NULL ]
或
# delete columns 3, 5 and 10 to 15
dt[ , (c(3,5,10:15)) := NULL ]
答案 2 :(得分:3)
我很惊讶没有提供使用set()
函数的答案。
set(DT, , colsToDelete, NULL)
这应该是最简单的。
答案 3 :(得分:0)
这段代码为我完成了这项工作。您需要具有要删除的列的位置,例如 posvec
中提到的 ?set
j:要赋值的列名(字符)或数字(整数) 当列已经存在时,只有列名,如果他们要 被创建。
DT_removed_slected_col = set(DT, j = posvec, value = NULL)
另外,如果你想获得 posvec
,你可以试试这个:
selected_col = c('col_a','col_b',...)
selected_col = unlist(sapply(selected_col, function(x) grep(x,names(DT))))
namvec = names(selected_col) #col names
posvec = unname(selected_col) #col positions