我有一个包含列表条目的列表,我需要转置结构.原始结构是矩形,但子列表中的名称不匹配.
这是一个例子:
ax <- data.frame(a=1,x=2)
ay <- data.frame(a=3,y=4)
bw <- data.frame(b=5,w=6)
bz <- data.frame(b=7,z=8)
before <- list( a=list(x=ax, y=ay), b=list(w=bw, z=bz))
Run Code Online (Sandbox Code Playgroud)
我想要的是:
after <- list(w.x=list(a=ax, b=bw), y.z=list(a=ay, b=bz))
Run Code Online (Sandbox Code Playgroud)
我不关心结果列表的名称(在任何级别).
显然,这可以明确地完成:
after <- list(x.w=list(a=before$a$x, b=before$b$w), y.z=list(a=before$a$y, b=before$b$z))
Run Code Online (Sandbox Code Playgroud)
但这很难看,只适用于2x2结构.这样做的惯用方法是什么?
Vic*_* K. 19
下面的代码将创建一个列表,其中包含每个列表的第i个元素before
:
lapply(before, "[[", i)
Run Code Online (Sandbox Code Playgroud)
现在你必须这样做
n <- length(before[[1]]) # assuming all lists in before have the same length
lapply(1:n, function(i) lapply(before, "[[", i))
Run Code Online (Sandbox Code Playgroud)
它应该给你你想要的东西.它效率不高(每次列表多次传输),你可以通过保持指向当前列表元素的指针来提高效率,所以请确定这对你来说是否足够好.
该purrr
软件包现在使这个过程非常简单:
library(purrr)
before %>% transpose()
## $x
## $x$a
## a x
## 1 1 2
##
## $x$b
## b w
## 1 5 6
##
##
## $y
## $y$a
## a y
## 1 3 4
##
## $y$b
## b z
## 1 7 8
Run Code Online (Sandbox Code Playgroud)
这是一个不同的想法 - 使用data.table
可以存储data.frame
的事实(事实上,考虑到你的问题,也许你甚至不需要使用列表列表,只能使用它们data.table
):
library(data.table)
dt = as.data.table(before)
after = as.list(data.table(t(dt)))
Run Code Online (Sandbox Code Playgroud)