我有一个包含许多其他列表的列表,每个列表包含不同数量的字符向量和不同数量的元素。我想创建一个数据框,其中每个列表将被表示为一行,而列表中的每个字符向量将是一列。如果字符向量具有> 1个元素,则这些元素将使用“ +”号进行连接和分隔,以便可以将它们存储为一个字符串。数据如下:
fruits <- list(
list(c("orange"), c("pear")),
list(c("pear", "orange")),
list(c("lemon", "apple"),
c("pear"),
c("grape"),
c("apple"))
)
预期输出如下:
fruits_df <- data.frame(col1 = c("orange", "pear + orange", "lemon + apple"),
col2 = c("pear", NA, "pear"),
col3 = c(NA, NA, "grape"),
col4 = c(NA, NA, "apple"))
列表中可以包含的字符向量数量没有限制,因此该解决方案需要动态创建列,从而导致df,其中列数等于包含最大列的列表的长度字符向量的数量。
答案 0 :(得分:2)
这有点混乱,但这是一种方法
cols <- lapply(fruits, function(x) sapply(x, paste, collapse=" + "))
ncols <- max(lengths(cols))
dd <- do.call("rbind.data.frame", lapply(cols, function(x) {length(x) <- ncols; x}))
names(dd) <- paste0("col", 1:ncol(dd))
dd
# col1 col2 col3 col4
# 1 orange pear <NA> <NA>
# 2 pear + orange <NA> <NA> <NA>
# 3 lemon + apple pear grape apple
或其他策略
ncols <- max(lengths(fruits))
dd <- data.frame(lapply(seq.int(ncols), function(x) sapply(fruits, function(y) paste(unlist(y[x]), collapse=" + "))))
names(dd) <- paste0("col", 1:ncols)
dd
但是实际上,您需要从列表中构建每一列或每一行,然后将它们组合在一起。
答案 1 :(得分:2)
对于fruits
中的每个列表,您可以创建一个单行数据框并绑定数据。
dplyr::bind_rows(lapply(fruits, function(x) as.data.frame(t(sapply(x,
function(y) paste0(y, collapse = "+"))))))
# V1 V2 V3 V4
#1 orange pear <NA> <NA>
#2 pear+orange <NA> <NA> <NA>
#3 lemon+apple pear grape apple
答案 2 :(得分:1)
另一种方法是使用rrapply::rrapply
将列表融合到data.frame,然后使用data.table::dcast
将其转换为所需的格式:
library(rrapply)
library(data.table)
## melt to long data.frame
long <- rrapply(fruits, f = paste, how = "melt", collapse = " + ")
## cast to wide data.table
setDT(long)
dcast(long[, .(L1, L2, value = unlist(value))], L1 ~ L2)[, !"L1"]
#> ..1 ..2 ..3 ..4
#> 1: orange pear <NA> <NA>
#> 2: pear + orange <NA> <NA> <NA>
#> 3: lemon + apple pear grape apple