【问题标题】:R: dynamically generate column-parsing code for dynamically named column in data tableR:为数据表中动态命名的列动态生成列解析代码
【发布时间】:2015-07-10 23:14:23
【问题描述】:

我正在尝试将一些旧代码从数据框实现移动到数据表。最初,我从 .csv 文件中获取数据,其中一些单元格包含数组,这些数组通过 fread 转换为字符串,如下所示:

> mydata$sport[1]
[1] "[24, 18, 24, 18]"

我想将这些字符串解析为数值数组。这是我作为第一步所做的部分工作(去掉括号,第 2 步,此处未显示,是转换为数值数组):

> name = "ascent"
> paste0(name, ":=strsplit(gsub('^\\[|\\]$','',", name, "),',')")
[1] "ascent:=strsplit(gsub('^\\[|\\]$','',ascent),',')"
 #here I manually copy the result of paste0 into the datatable command
 #I want to automate this setup, so this all can be put in a for loop
 #for many names
> mydata[, ascent:=strsplit(gsub('^\\[|\\]$','',ascent),',')]
> mydata$ascent[10]
[[1]]
[1] "-999"  " -999"

所以我生成的用于修改的命令很好,但是我有很多names我想这样做,所以我不想手动复制和粘贴,如上所述。我尝试使用eval 此处讨论的技巧dynamic column names in data.table, R

但是一旦我介绍了eval,代码就不起作用了:

> name = "ascent"
> mydata[, eval(paste0(name, ":=strsplit(gsub('^\\[|\\]$','',", name, "),',')"))]
[1] "ascent:=strsplit(gsub('^\\[|\\]$','',ascent),',')"

那么我怎样才能实现它以适用于任意名称,而不必通过 paste0 为每个所需名称手动创建命令?我有一个 names 的整个向量,我想要做这个修改。

这是fread 之后和进行任何修改之前的数据表:

> mydata[1:10, .(sport, ascent)]
                             sport                                                       ascent
 1:               [24, 18, 24, 18]                                   [-999, 140.0, -999, 140.0]
 2: [2, 2, 2, 22]                                                    [-999, -999, -999, -999]
 3:       [-999, -999, -999, -999]                                     [-999, -999, -999, -999]
 4:                   [-999, -999]                                               [173.0, 173.0]
 5:                       [18, 18]                                                 [-999, -999]
 6:                         [-999]                                                       [-999]
 7:                         [-999]                                                       [-999]
 8:                         [-999]                                                       [-999]
 9:                   [-999, -999]                                                 [-999, -999]
10:                   [-999, -999]                                                 [-999, -999]

【问题讨论】:

  • 您不必以这种方式编写代码来删除所有列的括号。你可以lapply(mydata, function(x) gsub('^\\[|\\]$','', x))

标签: r data.table


【解决方案1】:

根本不要使用这些名字...

for(j in which(names(mydata) %in% names)) set(mydata,i=NULL,j=j,value=strsplit(gsub('^\\[|\\]$','',mydata[[j]]),','))

顺便说一句,eval 需要 parse 以您尝试使用它的方式工作,例如 eval(parse(text=paste0(name,":=1+1")))

【讨论】:

  • 感谢您的建议,但由于我不想对所有列执行此操作,因此必须跟踪哪些列号而不是我想引用哪些列名会很尴尬,我认为这个解决方案行不通。
  • 查看编辑。这应该只适用于名为names 的向量。
  • @sunny 编辑解决了您的问题吗?如果是这样,您介意接受答案吗?
  • 是的,编辑确实解决了问题。我会接受你的回答,但我仍然希望找到一种方法来避免 for 循环。
  • 实际上,如果您查看 cmets 来回答这个问题 stackoverflow.com/questions/16846380/…,您会发现 data.table 的创建者更喜欢这种类型的事情的 for 循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 2015-04-04
  • 1970-01-01
相关资源
最近更新 更多