【问题标题】:How to subset rows when looping through a list of data.tables?循环遍历data.tables列表时如何对行进行子集化?
【发布时间】:2019-03-15 10:07:09
【问题描述】:

我正在使用 R 中的大量 data.tables。我已将 data.tables 放在一个列表中,如下例所示:

dt1 <- data.table(v1 = c("a","a","a"), v2 = 1:3)
dt2 <- data.table(v1 = c("notes","a","a"), v2 = 1:3)
dt3 <- data.table(v1 = c("notes","a","a"), v2 = 1:3)

dt_list <- list(dt1, dt2, dt3)

我想对列表中的每个 data.table 执行一组操作。例如,在 v1 中删除带有“注释”的行,并添加新列。

列操作按我的预期工作(尽管我的环境中出现了一个新的 data.table dt):

for (dt in dt_list) {
  dt <- dt[, newvar := "new"]
} 

dt2
          v1 v2 newvar
    1: notes  1    new
    2:     a  2    new
    3:     a  3    new

但是,行操作似乎不会以相同的方式编辑 data.tables:

for (dt in dt_list) {
  dt <- dt[v1 != "notes", ]
}

dt2
          v1 v2 newvar
    1: notes  1    new
    2:     a  2    new
    3:     a  3    new

for 循环中的代码确实适用于单个 data.table,因此问题似乎是由使用 for 和/或 list 引起的:

dt2 <- dt2[v1 != "notes"]
dt2
       v1 v2 newvar
    1:  a  2    new
    2:  a  3    new

我已经针对其他行操作对此进行了测试,并遇到了同样的问题。有没有一种方法可以删除列表中所有 data.tables 的 v1 中包含“注释”的行?

提前谢谢你。

【问题讨论】:

  • lapply(dt_list, function(dt) dt[v1 != "notes"])
  • 另外lapply(dt_list, function(x) x[v1 != "notes"][, newvar := "new"])
  • 合并表格操作会少很多麻烦DT = rbindlist(dt_list, id="dt_num")

标签: r data.table


【解决方案1】:

data.table 包允许您使用set 函数或:= 运算符通过引用更改对象的值。赋值运算符&lt;- 没有这样的默认行为。因此,如果您将第一个循环替换为:

for (dt in dt_list) {
  dt[, newvar := "new"]
} 

它会产生相同的效果。您只需使用:= 即可更改dt。另一方面,如果您不使用它,更改将不会反映在您的原始数据中。目前,我不相信您可以使用data.table 通过引用删除或子集行,因此您需要按照@jogo 或@markus 的建议创建一个新列表

dt_list2<-lapply(dt_list, function(dt) dt[v1 != "notes"])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多