将多个列表组合到一个数据框R
Combining multiple lists to a data frame R
以下只是我全部数据的一小部分MWE。假设我有一个包含以下格式的两个矩阵的列表
dat1 <- matrix(rnorm(3*5), nrow = 5, ncol =3)
colnames(dat1) <- c("power_FX", "power_MX_LLSM" ,"power_MX_LCD")
rownames(dat1) <- c("nu=1", "nu=3", "nu=5", "nu=10", "nu=30")
dat2 <- matrix(rnorm(3*5), nrow = 5, ncol =3)
colnames(dat2) <- c("power_FX", "power_MX_LLSM" ,"power_MX_LCD")
rownames(dat2) <- c("nu=1", "nu=3", "nu=5", "nu=10", "nu=30")
list.dat <- list(n600 = dat1, n700 = dat2)
我想将列表中的这两个矩阵组合成一个包含 4 列的数据框:一列用于列表名称,一列用于矩阵的行名称,一列用于矩阵的列名称,一列包含数值:
n nu type value
600 1 power_FX ...
600 1 power_MX_LLSM ...
. . ... ...
600 3 power_FX ...
600 3 power_MX_LLSM ...
您可以对 lapply()
中的每个列表元素进行转换,然后将所有内容与 do.call("rbind", ...)
绑定在一起。大多数转换是由 reshape2::melt()
完成的,它有一个矩阵方法,可以完成您想要的大部分操作。
df <- do.call("rbind",
lapply(seq_along(list.dat), function(l) {
tmp <- cbind(n = names(list.dat[l]), reshape2::melt(list.dat[[l]], varnames = c("nu", "type")))
tmp$n <- as.numeric(gsub("n", "", tmp$n))
tmp$nu <- as.numeric(gsub("nu=", "", tmp$nu))
tmp
})
)
这是使用 tidyverse
-
的方法
library(tidyverse)
list.dat %>%
map_df(~.x %>% as.data.frame %>% rownames_to_column('nu'), .id = 'n') %>%
mutate(across(c(n, nu), parse_number)) %>%
pivot_longer(cols = starts_with('power'), names_to = 'type')
# n nu type value
# <dbl> <dbl> <chr> <dbl>
# 1 600 1 power_FX -0.524
# 2 600 1 power_MX_LLSM 0.102
# 3 600 1 power_MX_LCD 1.41
# 4 600 3 power_FX 0.494
# 5 600 3 power_MX_LLSM 0.492
# 6 600 3 power_MX_LCD -0.383
# 7 600 5 power_FX -0.334
# 8 600 5 power_MX_LLSM -0.558
# 9 600 5 power_MX_LCD 0.474
#10 600 10 power_FX -0.0823
# … with 20 more rows
以下只是我全部数据的一小部分MWE。假设我有一个包含以下格式的两个矩阵的列表
dat1 <- matrix(rnorm(3*5), nrow = 5, ncol =3)
colnames(dat1) <- c("power_FX", "power_MX_LLSM" ,"power_MX_LCD")
rownames(dat1) <- c("nu=1", "nu=3", "nu=5", "nu=10", "nu=30")
dat2 <- matrix(rnorm(3*5), nrow = 5, ncol =3)
colnames(dat2) <- c("power_FX", "power_MX_LLSM" ,"power_MX_LCD")
rownames(dat2) <- c("nu=1", "nu=3", "nu=5", "nu=10", "nu=30")
list.dat <- list(n600 = dat1, n700 = dat2)
我想将列表中的这两个矩阵组合成一个包含 4 列的数据框:一列用于列表名称,一列用于矩阵的行名称,一列用于矩阵的列名称,一列包含数值:
n nu type value
600 1 power_FX ...
600 1 power_MX_LLSM ...
. . ... ...
600 3 power_FX ...
600 3 power_MX_LLSM ...
您可以对 lapply()
中的每个列表元素进行转换,然后将所有内容与 do.call("rbind", ...)
绑定在一起。大多数转换是由 reshape2::melt()
完成的,它有一个矩阵方法,可以完成您想要的大部分操作。
df <- do.call("rbind",
lapply(seq_along(list.dat), function(l) {
tmp <- cbind(n = names(list.dat[l]), reshape2::melt(list.dat[[l]], varnames = c("nu", "type")))
tmp$n <- as.numeric(gsub("n", "", tmp$n))
tmp$nu <- as.numeric(gsub("nu=", "", tmp$nu))
tmp
})
)
这是使用 tidyverse
-
library(tidyverse)
list.dat %>%
map_df(~.x %>% as.data.frame %>% rownames_to_column('nu'), .id = 'n') %>%
mutate(across(c(n, nu), parse_number)) %>%
pivot_longer(cols = starts_with('power'), names_to = 'type')
# n nu type value
# <dbl> <dbl> <chr> <dbl>
# 1 600 1 power_FX -0.524
# 2 600 1 power_MX_LLSM 0.102
# 3 600 1 power_MX_LCD 1.41
# 4 600 3 power_FX 0.494
# 5 600 3 power_MX_LLSM 0.492
# 6 600 3 power_MX_LCD -0.383
# 7 600 5 power_FX -0.334
# 8 600 5 power_MX_LLSM -0.558
# 9 600 5 power_MX_LCD 0.474
#10 600 10 power_FX -0.0823
# … with 20 more rows