R:如何在循环中cbind嵌套循环的所有数据帧的特定列?

时间:2017-06-23 16:18:44

标签: r list nested-loops cbind

我试图在同一个循环过程中组合几个数据帧的第三列,这些数据帧在嵌套for循环中调用和重命名。

# Sample Data
ecvec_msa6_1998=matrix( round(rnorm(200, 5,15)), ncol=4)
ecvec_msa6_1999=matrix( round(rnorm(200, 4,16)), ncol=4)
ecvec_msa6_2000=matrix( round(rnorm(200, 3,17)), ncol=4)

datasets=c("msa")
num_industrys=c(6)
years=c(1998, 1999, 2000)

alist=list() 

for (d in 1:length(datasets)) {
  dataset=datasets[d]
  for (n in 1:length(num_industrys)){
    num_industry=num_industrys[n]
    for (y in 1:length(years)) {
      year=years[y]

     eval(parse(text=paste0("newly_added = ecvec_", dataset, num_industry, "_",  year))) 
     # renaming the old data frames

     alist = list(alist, newly_added) # combining them in a list

     extracted_cols <- lapply(alist, function(x) x[3]) # selecting the third column

     result <- do.call("cbind", extracted_cols) # trying to cbind the third colum

    }
  }
}

有人能告诉我正确的方法吗?

3 个答案:

答案 0 :(得分:1)

通常建议避免在R:

中嵌套循环

See Circle 2 of R's Infernohere

也许你应该尝试替换这部分

     extracted_cols <- lapply(alist, function(x) x[3]) # selecting the third column

     result <- do.call("cbind", extracted_cols) # trying to cbind the third colum
像帕特里克·伯恩斯这样的名单已经在第一个链接中完成了它(第14页)。它也可以更清洁。

答案 1 :(得分:0)

您是否只想提取并将每个数据框中的第三列合并为一个新列?

newdata <- cbind(ecvec_msa6_1998[,3],ecvec_msa6_1999[,3],ecvec_msa6_2000[,3])

答案 2 :(得分:0)

您的代码几乎可以运作 - 这里有一些变化......

alist=list() 

for (d in 1:length(datasets)) {
  dataset=datasets[d]
  for (n in 1:length(num_industrys)){
    num_industry=num_industrys[n]
    for (y in 1:length(years)) {
      year=years[y]
      eval(parse(text=paste0("newly_added = ecvec_", dataset, num_industry, "_",  year)))                                   
      #the next line produces the sort of list you want - yours was too nested
      alist = c(alist, list(newly_added))
    }
  }
}

#once you have your list, these commands should be outside the loop          
extracted_cols <- lapply(alist, function(x) x[,3]) #note the added comma!
result <- do.call(cbind, extracted_cols) #no quotes needed around cbind

head(result)
     [,1] [,2] [,3]
[1,]   11   13   24
[2,]  -26   -3    7
[3,]   -1  -26  -14
[4,]    5   14  -15
[5,]   28    3    8
[6,]    9   -9   19

然而 - 更多类似R(更快)的做法是用

取代上述所有内容
df <- expand.grid(datasets,num_industrys,years) #generate all combinations
datanames <- paste0("ecvec_",df$Var1,df$Var2,"_",df$Var3) #paste them into a vector of names
result <- sapply(datanames,function(x) get(x)[,3])

sapply会自动将列表简化为数据框(如果可以lapply始终生成列表)