在 R 中有效地将数据从数据帧列表重新排列为数组?



我有如下排列的数据

  • 一个列表
  • 在列表中,每个元素都是一个数据框(50 个数据框)
  • 每个数据框
  • 都包含 5 行数字,其中 9 个命名列(所有 50 个数据框的名称相同 9 个)

的目标是有效地重新排列这些数据,以便

  • "第二维度"(在上述描述中从 1 到 5 的范围)成为第一个维度。
  • "第一维度"(在上述描述中从 1 到 50 的范围)成为第二个维度。
  • 我只保留 9 个命名列中的一些(其余的可以丢弃),按名称选择
  • 我希望所有数字都存储在一个数组中(或者另一个更有效的数据结构也可以),而不是这些低效的列表和数据帧。

可以使用以下代码生成示例数据(简化为只有 2 个数据框,每个数据框 5 行 3 列):

example_list<-lapply(X=1:2, FUN=function(X){setNames(data.frame(X*c(1:5), -X*c(1:5), X*100*c(1:5)), c("C1", "C2", "C3"))})

这将创建以下两个数据框的列表:

> example_list[1]
C1 C2  C3
1  1 -1 100
2  2 -2 200
3  3 -3 300
4  4 -4 400
5  5 -5 500
> example_list[2]
C1  C2   C3
1  2  -2  200
2  4  -4  400
3  6  -6  600
4  8  -8  800
5 10 -10 1000

当前的解决方案(示例数据使用硬编码数字)如下所示。在这种情况下,我假设我们只关心名为"C1"和"C2"的列:

important_cols <- c("C1", "C2")
result <- array(0, c(5, 2, length(important_cols)))
for(i in 1:5){
for(j in 1:2){
result[i,j,] <- c(example_list[[j]][i,important_cols], recursive=T)
}
}

这给出了以下输出:

> result
, , 1
[,1] [,2]
[1,]    1    2
[2,]    2    4
[3,]    3    6
[4,]    4    8
[5,]    5   10
, , 2
[,1] [,2]
[1,]   -1   -2
[2,]   -2   -4
[3,]   -3   -6
[4,]   -4   -8
[5,]   -5  -10

例如,result[5,2,] = [10, -10]对应于原始数据的第2个数据帧的第5行(删除了第三列)。


上面的解决方案有效,但我不禁怀疑应该有一个比双手动实现的 for 循环和逐个设置所有元素更有效的解决方案。

您可以使用一些lapplypurrr::transpose来避免循环:

# Example
N <- 1e5
example_list <-
lapply(
X = 1:2,
FUN = function(X) {
setNames(data.frame(X * c(1:N), -X * c(1:N), X * 100 * c(1:N)), c("C1", "C2", "C3"))
}
)
important_cols <- c("C1", "C2")    
# Your solution -> 58 seconds :O
system.time({
result <- array(0, c(N, 2, length(important_cols)))
for(i in 1:N){
for(j in 1:2){
result[i,j,] <- c(example_list[[j]][i,important_cols], recursive=T)
}
}
})
# Solution with purrr::transpose -> 0 sec    
library(magrittr)  ## for the %>%
system.time({
result2 <- example_list %>%
lapply(function(df) df[important_cols]) %>%
purrr::transpose() %>%
sapply(function(l) do.call(cbind, l))
})
dim(result2) <- c(nrow(example_list[[1]]), 
length(example_list), 
length(important_cols))
# Verification
all.equal(result, result2)

最新更新