当使用:=时,动态列名称似乎有效,但在data.table中使用=时,动态列名称无效

时间:2019-06-20 12:21:27

标签: r data.table eval dynamic-columns

使用此虚拟数据集

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}})

3 个答案:

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