data.table将列添加到循环

时间:2016-05-05 20:26:32

标签: r data.table

我有一个非常简单的问题,但还没有找到解决方法。我从不同的商店获得了大约200张桌子,并且必须分析整个数据作为一个单元。由于表格相当大,我正在使用data.table::fread。我的计划是加载每个表,rbind将它们放在一起并继续进行分析。为了保留哪个商店,我想在每个表中添加一个变量商店,并使用商店的名称(与表相同)。为此,我计划使用表的名称运行for循环并创建新变量。

# I'll create some dummy data tables here. In reality they're loaded with fread
library(data.table)
centro <- data.table(x=letters[1:5], y = 1:5)
sur <- data.table(x=letters[2:7], y = 3:8)
...
norte <- data.table(x=letters[2:10], y = 3:11)

我需要每个表都有一个变量&#34; store&#34;其价值是&#34; centro&#34;,&#34; sur&#34;或者&#34; norte&#34;,取决于它所属的商店。所以我试过了:

st <- c("centro", "sur", "norte")
for (i in st){
   i[, store := i]
}

当然,这不起作用(它抱怨&#34;我不是数据表。&#34;)。然后我尝试创建一个列表并通过lapply

进行尝试
sts <- list(centro, sur, norte)
sts <- lapply(sts, function(z) z[, store := names(z)])

哪个不起作用,因为names(z)是&#34; x&#34;,&#34; y&#34;和&#34;存储&#34;。

如何使用循环(或* pply函数)执行此操作,而不是手动执行xyz[, store := "xyz"]

旁注

  • 变量的命名几乎无法调整,也不会遵循任何模式(没有像store_1,store_2等)
  • 我可能对我描述的替代方案非常偏颇。任何其他有用的东西都可以。

3 个答案:

答案 0 :(得分:3)

最好的方法是将对象存储在列表中,然后通过索引列表来访问它们。

library(data.table)

my_dts <- list (
  centro = data.table(x=letters[1:5], y = 1:5),
  sur = data.table(x=letters[2:7], y = 3:8),
  norte = data.table(x=letters[2:10], y = 3:11)
)

st <- c("centro", "sur", "norte")
for (i in st) my_dts[[i]][, store := i]

答案 1 :(得分:1)

直接回答,变化很小

get周围包裹i,并将值分配回i中包含的名称。

for (i in st){
  assign(i, get(i)[, store := i])
}

更好的系统,一些操纵

将表存储在列表中并使用建议的方法@ arvi1000。 一对非常明显的优势

  1. 由于您的各个商店都是列表中的所有商品,因此您的工作区中的对象数量减少了约200个,这在您ls()时很不错。
  2. 您可以使用lapply代替for循环,这通常意味着更清晰的代码
  3. 您可以使用AllStore <- do.call(what = rbind, args = my_dts)
  4. '更好',回到开头

    • 当您从不同商店读取数据时,请设置值 store变量然后。使用lapply和匿名函数执行此操作。
    • 不要费心保存my_dts列表,因为 它只是重复将保存在all_stores中的数据 反正。

    巧合的是,上周我遇到了类似的业务问题,这是我使用的方法,使用大约250个csvs。以下是我认为您的代码看起来的样子。

    st <- c("centro", "sur", "norte")
    
    all_stores <- do.call(
      what = rbind,
      args = lapply(
        X = st,
        FUN = function(storeNM){
          temp <- fread(input = paste0(storeNM, '.csv'))
          temp[, store := storeNM]
          return(temp)
        }
      )
    )
    

答案 2 :(得分:0)

试试这个:

for (i in st)
{
eval(parse(text=i))[, ':='(store = i)]
}

第二个想法,可能这更好。假设您已使用s<-lapply(filepathlist,fread)读入所有数据集,请使用:

st <- c("centro", "sur", "norte") # need to change this to a list of datasets you read in    
st2<-lapply(st,function(i){eval(parse(text=i))[, ':='(store = i)]})
st3<-rbindlist(st2)

输出:

    > st3
        x  y  store
     1: a  1 centro
     2: b  2 centro
     3: c  3 centro
     4: d  4 centro
     5: e  5 centro
     6: b  3    sur
     7: c  4    sur
     8: d  5    sur
     9: e  6    sur
    10: f  7    sur
    11: g  8    sur
    12: b  3  norte
    13: c  4  norte
    14: d  5  norte
    15: e  6  norte
    16: f  7  norte
    17: g  8  norte
    18: h  9  norte
    19: i 10  norte
    20: j 11  norte