使用此虚拟数据集
setDT(mtcars_copy<-copy(mtcars))
new_col<- "sum_carb" # for dynamic column referencing
为什么情况1起作用但情况2不起作用?
# Case 1 - Works fine
mtcars_copy[,eval(new_col):=sum(carb)] # Works fine
# Case 2:Doesnt work
aggregate_mtcars<-mtcars_copy[,(eval(new_col)=sum(carb))] # error
aggregate_mtcars<-mtcars_copy[,eval(new_col)=sum(carb))] # error
aggregate_mtcars<-mtcars_copy[,c(eval(new_col)=sum(carb))] # Error
如何使Case 2
起作用,其中我不希望主表(在这种情况下为mtcars_copy
来容纳新列),而结果却存储在单独的聚合表中({ {1}})
答案 0 :(得分:2)
我认为您想要做的是在做案例1时简单地复制一份。
aggregate_mtcars <- copy(mtcars_copy)[, eval(new_col) := sum(carb)]
这将mtcars_copy
保留为新aggregate_metcars
的单独数据集,而没有新的列。
答案 1 :(得分:2)
一种选择是使用基本R函数setNames
aggregate_mtcars <- mtcars_copy[, setNames(.(sum(carb)), new_col)]
或者您可以使用data.table::setnames
aggregate_mtcars <- setnames(mtcars_copy[, .(sum(carb))], new_col)
答案 2 :(得分:1)
原因是因为案例2使用data.frame
的方式在数据框中创建列(作为新列表)。
data.table:with
中有一个隐藏参数,用于处理返回对象的方式。它可以是数据表或向量。
?data.table:
默认情况下,with = TRUE,并且j在x的框架内求值;列名称可用作变量。如果数据集内部和父范围中的变量名称重叠,则可以使用双点前缀..cols显式引用'cols变量父范围,而不是来自数据集。当j是列名称的字符向量时,要选择的列位置的数字向量或格式为startcol:endcol,并且返回的值始终是data.table。 with = FALSE不再需要动态选择列。请注意,x [,cols]等效于x [,..cols]和x [,cols,具有= FALSE]和x [,.SD,.SDcols = cols]。
# Case 2 :
aggregate_mtcars<-mtcars_copy[,(get(new_col)=sum(carb))] # error
aggregate_mtcars<-mtcars_copy[,eval(new_col)=sum(carb))] # error
aggregate_mtcars<-mtcars_copy[,c(eval(new_col)=sum(carb))] # Error
mtcars_copy[, new_col, with = FALSE ] # gives a data.table
mtcars_copy[, eval(new_col), with = FALSE ] # this works and create a data.table
mtcars_copy[, eval(new_col), with = TRUE ] # the default that is used here with error
mtcars_copy[, get(new_col), with = TRUE ] # works and gives a vector
# Case 2 solution : affecting values the data.frame way
mtcars_copy[, eval(new_col) ] <- sum(mtcars_copy$carb) # or any vector
mtcars_copy[[eval(new_col)]] <- sum(mtcars_copy$carb) # or any vector