以特定方式组合列表中的数据帧列表

时间:2016-08-03 15:15:40

标签: r list dataframe

我有一个列表,其中包含另一个数据框列表。 外部列表元素表示年份,内部列表表示月份数据。

现在我想创建一个包含所有月份数据的最终列表。每个月的列将是" cbinded"按其他年份列值。

   Alldata <- list()

Alldata[[1]] <- list(data.frame(Jan_2015_A=c(1,2), Jan_2015_B=c(3,4)), data.frame(Feb_2015_C=c(5,6), Feb_2015_D=c(7,8)))
Alldata[[2]] <- list(data.frame(Jan_2016_A=c(1,2), Jan_2016_B=c(3,4)), data.frame(Feb_2016_C=c(5,6), Feb_2016_D=c(7,8)))

预期输出列表如下

enter image description here

我尝试过使用for循环及其复杂功能,我希望任何R函数都能完成此任务。

我使用以下代码使用for循环完成了此操作。但这真的很复杂,我自己发现这有点复杂。希望我能为此操作获得更简单,更整洁的代码。

我创建了包含每个月和年数据的列表作为数据框形式的列表项

x2 <- list()

for(l1 in 1: length(Alldata[[1]])){
  temp <- list()
  for(l2 in 1: length(Alldata)){


    temp <- append(temp, list(Alldata[[l2]][[l1]]))

  }

  x2 <- append(x2, list(temp))
}

# then created final List with succesive years data of each month as list items. This is primarily used for Tracking data for years For Example:  how much was count was for Jan_2015 and Jan_2016 for "A"
finalList <- list()
for(l3 in 1: length(x2)){

  temp <- x2[[l3]]
  td2 <-  as.data.frame(matrix("", nrow = nrow(temp[[1]])))
  rownames(td2)[rownames(temp[[1]])!=""] <- rownames(temp[[1]])[rownames(temp[[1]])!=""]
  for(l4 in 1:ncol(temp[[1]])){
    for(l5 in 1: length(temp)){

      # lapply(l4, function(x)  do.call(cbind, 
      td2 <- cbind(td2, temp[[l5]][, l4, drop=F])
    }

  }

  finalList <- append(finalList, list(td2))

}

> finalList
[[1]]
  V1 Jan_2015_A Jan_2016_A Jan_2015_B Jan_2016_B
1             1          1          3          3
2             2          2          4          4

[[2]]
  V1 Feb_2015_C Feb_2016_C Feb_2015_D Feb_2016_D
1             5          5          7          7
2             6          6          8          8

1 个答案:

答案 0 :(得分:2)

您可以执行以下操作。 lapply将遍历外部列表,do.callcbind内部数据框列表。

lapply(Alldata, do.call, what = 'cbind')
[[1]]
  Jan_2015_A Jan_2015_B Feb_2015_C Feb_2015_D
1          1          3          5          7
2          2          4          6          8

[[2]]
  Jan_2016_A Jan_2016_B Feb_2016_C Feb_2016_D
1          1          3          5          7
2          2          4          6          8

您也可以使用dplyr获得相同的结果。

library(dplyr)
lapply(Alldata, bind_cols)

这是J.R。

提出的第三种选择
lapply(Alldata, Reduce, f = cbind)

修改

在OP澄清之后,上述解决方案已被修改(见下文)以产生新指定的输出。上面的解决方案已经留在那里,因为它是下面解决方案的构建块。

pattern.vec <- c("Jan", "Feb")
### For a given vector of months/patterns, returns a
### list of elements with only that month.
mon_data <- function(mo) {
  return(bind_cols(sapply(Alldata, function(x) { x[grep(pattern = mo, x)]})))
}
### Loop through months/patterns.
finalList <- lapply(pattern.vec, mon_data)
finalList

## [[1]]
##   Jan_2015_A Jan_2015_B Jan_2016_A Jan_2016_B
## 1          1          3          1          3
## 2          2          4          2          4
## 
## [[2]]
##   Feb_2015_C Feb_2015_D Feb_2016_C Feb_2016_D
## 1          5          7          5          7
## 2          6          8          6          8

## Ordering the columns as specified in the original question.
## sorting is by the last character in the column name (A or B)
## and then the year.
lapply(finalList, function(x) x[ order(gsub('[^_]+_([^_]+)_(.*)', '\\2_\\1', colnames(x))) ])
## [[1]]
##   Jan_2015_A Jan_2016_A Jan_2015_B Jan_2016_B
## 1          1          1          3          3
## 2          2          2          4          4
## 
## [[2]]
##   Feb_2015_C Feb_2016_C Feb_2015_D Feb_2016_D
## 1          5          5          7          7
## 2          6          6          8          8