2017-05-31 60 views
-1

我正在通过循环创建一系列data.tables,其中每个表名称和列都依赖于循环。使用变量作为data.table中的列名称

我发现我可以使用assign创建表格,然后使用eval(as.name(tbl))然后调用它似乎工作正常。列名似乎并不像我想要的那样行事?

要生成列名称,我使用capture.output(str(tbl, give.head = F)),它的工作原理是,但是当我想引用列时,它被双引号括起来,例如, "name_win_pcnt"

我似乎无法引用列,所以如果我使用name_win_pcnt $“name_win_pcnt”我在控制台中得到一个NULL。

下面是一个例子。

require(data.table) 
# initial data table 
dt <- data.table(x = rnorm(10), 
      y = rnorm(10), 
      grp = c(rep("a",3), rep("b",7)))) 

#variables 
metric <- c("win", "place") 
cols <- "name" 

tbl <- paste0(cols, "_", metric[1],"_pcnt") 

# create new table and create new column 
assign(tbl, dt, envir = .GlobalEnv) 
eval(as.name(tbl))[, capture.output(str(tbl, give.head = F)) := 0L, by = .(grp)] 

如果我现在尝试使用

eval(as.name(tbl))[, eval(tbl) := 1L, by = .(grp)]这造成了我一个新列,但留下的旧更新新列?

我试着用eval(as.name(tbl))[, eval(tbl) := 0L]添加列,但后来当我尝试更新它,我得到一个错误:

Error in is.nan(name_win_pcnt) : 
    default method not implemented for type 'list' 
+2

不要使用'assign'。将所有这些data.tables放在一个列表中。 – Roland

+0

我使用外部循环一次创建表1。为什么我应该避免分配? – MidnightDataGeek

+1

由于遇到的种种问题...'assign'适用于知道何时需要(几乎从不)的专家。使用列表(或环境)是“R方式”。 – Roland

回答

1

我认为set命令的用法会比较在data.table包的精神并可以完成这项工作。

set(x=eval(as.name(tbl)), j=tbl, value=2L) 

这样,列名中不会有引号。

虽然你没有问,但我觉得使用list来保存所有data.tables将会更好地使用R的数据结构。

+0

道歉我应该提到我使用我需要对组进行操作,所以我不认为'set'在这种情况下会起作用。 我会更新我的问题。 – MidnightDataGeek

+0

也许你可以先做子集操作,然后在中间结果的第二步中使用'set'?在第三步中,您可以使用'set'再次更新原始data.table中的数据。 – mondano

+0

谢谢做中间步骤似乎已经奏效。所以我使用我的原始方法创建列,然后使用set来更新它,它似乎可以解决问题。 看来使用变量在R中是非常艰苦的工作吗? – MidnightDataGeek