[英]Converting a complicated list to data.frame in R
我有一个清单
my_list = list("1" = list(year = 1900, values = c(1,2,3,4,5),
another_attribute = "hello"), "2" = list(year = 1901,
values = c(11,12,13,14,15), another_attribute = "thankyou"))
my_list
$`1`
$`1`$year
[1] 1900
$`1`$values
[1] 1 2 3 4 5
$`1`$another_attribute
[1] "hello"
$`2`
$`2`$year
[1] 1901
$`2`$values
[1] 11 12 13 14 15
$`2`$another_attribute
[1] "thankyou"
我想将其转换为data.frame或矩阵,其中值是行,年份是行名,例如
my_df = rbind(my_list$'1'$values, my_list$'2'$values)
如果可能,将行名称作为年份
rownames(my_df) = c(my_list$'1'$year, my_list$'2'$year)
my_df
[,1] [,2] [,3] [,4] [,5]
1900 1 2 3 4 5
1901 11 12 13 14 15
我想避免使用循环语句,可以在循环中提取每个属性,但是我想知道是否还有另一种时髦的方法。 因为这是一个很大的清单。
使用lapply
提取年份和值
library(magrittr)
lapply(my_list, "[", "values") %>%
as.data.frame() %>%
setNames(unlist(lapply(my_list, "[","year") )) %>%
t()
首先,必须更正您的示例列表:
my_list = list("1" = list(year = 1900, values = c(1,2,3,4,5),
another_attribute = "hello"), "2" = list(year = 1901,values =
c(11,12,13,14,15), another_attribute = "thankyou"))
然后,为列表的一个元素(即第一个内部列表)编写一个功能,该功能恰好满足您的要求。
entry2df <- function(el) {
df <- as.data.frame(t(el$values))
rownames(df) <- el$year
df
}
然后,您使用lapply
(将函数应用于列表的每个元素并将结果收集到结果列表中),然后执行rbind
Reduce
方法将这些单个数据帧的列表逐行绑定到一个数据帧。
Reduce(rbind, lapply(my_list, entry2df))
结果:
V1 V2 V3 V4 V5
1900 1 2 3 4 5
1901 11 12 13 14 15
使用Map
将各个部分拼合在一起,将其rbind
到一个矩阵中并制作一个data.frame:
data.frame(do.call(Map, c(rbind, my_list) ))
# year values.1 values.2 values.3 values.4 values.5 another_attribute
#1 1900 1 2 3 4 5 hello
#2 1901 11 12 13 14 15 thankyou
固定my_list
以便将another_attribute
放在第一和第二个列表中的位置:
my_list <- structure(list(`1` = structure(list(year = 1900, values = c(1,
2, 3, 4, 5), another_attribute = "hello"), .Names = c("year",
"values", "another_attribute")), `2` = structure(list(year = 1901,
values = c(11, 12, 13, 14, 15), another_attribute = "thankyou"), .Names = c("year",
"values", "another_attribute"))), .Names = c("1", "2"))
在基数R中:
mat <- t(sapply(my_list,`[[`,"values"))
rownames(mat) <- sapply(my_list,`[[`,"year")
mat
# [,1] [,2] [,3] [,4] [,5]
# 1900 1 2 3 4 5
# 1901 11 12 13 14 15
# Extracting the values
my_df <- t(sapply(1:length(my_list), function(x) my_list[[x]]$values))
my_df
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 2 3 4 5
# [2,] 11 12 13 14 15
# Making it a data.frame
my_df <- as.data.frame(my_df)
# Assining the correct row names
rownames(my_df) <- sapply(1:length(my_list), function(x) my_list[[x]]$year)
my_df
# V1 V2 V3 V4 V5
# 1900 1 2 3 4 5
# 1901 11 12 13 14 15
这是tidyverse
一个选择
library(tidyverse)
my_list %>%
map_df(~.x %>%
as_tibble %>%
select(year, values) %>%
mutate(rn = row_number()) ) %>%
spread(rn, values) %>%
as.data.frame %>%
column_to_rownames('year') %>%
as.matrix %>%
`colnames<-`(., NULL)
# [,1] [,2] [,3] [,4] [,5]
#1900 1 2 3 4 5
#1901 11 12 13 14 15
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.