繁体   English   中英

在R中将复杂列表转换为data.frame

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM