如何展平列表列表?

Posted

技术标签:

【中文标题】如何展平列表列表?【英文标题】:How to flatten a list of lists? 【发布时间】:2013-04-24 09:36:02 【问题描述】:

tm 包扩展了c,因此,如果给定一组PlainTextDocuments,它会自动创建一个Corpus。不幸的是,似乎每个PlainTextDocument 都必须单独指定。

例如如果我有:

foolist <- list(a, b, c); # where a,b,c are PlainTextDocument objects

我会这样做以获得Corpus

foocorpus <- c(foolist[[1]], foolist[[2]], foolist[[3]]);

我有一个'PlainTextDocuments 的列表,如下所示:

> str(sectioned)
List of 154
 $ :List of 6
  ..$ :Classes 'PlainTextDocument', 'TextDocument', 'character'  atomic [1:1] Developing assessment models   Developing models
  .. .. ..- attr(*, "Author")= chr "John Smith"
  .. .. ..- attr(*, "DateTimeStamp")= POSIXlt[1:1], format: "2013-04-30 12:03:49"
  .. .. ..- attr(*, "Description")= chr(0) 
  .. .. ..- attr(*, "Heading")= chr "Research Focus"
  .. .. ..- attr(*, "ID")= chr(0) 
  .. .. ..- attr(*, "Language")= chr(0) 
  .. .. ..- attr(*, "LocalMetaData")=List of 4
  .. .. .. ..$ foo           : chr "bar"
  .. .. .. ..$ classification: chr "Technician"
  .. .. .. ..$ team          : chr ""
  .. .. .. ..$ supervisor    : chr "Bill Jones"
  .. .. ..- attr(*, "Origin")= chr "Smith-John_e.txt"

#etc., all sublists have 6 elements

所以,要将我所有的 PlainTextDocuments 都放入 Corpus,这样可以:

sectioned.Corpus <- c(sectioned[[1]][[1]], sectioned[[1]][[2]], ..., sectioned[[154]][[6]])

谁能推荐一个更简单的方法,好吗?

ETA:foo&lt;-unlist(foolist, recursive=FALSE) 生成一个普通文本文档的平面列表,这仍然给我留下了将列表元素逐个元素提供给 c 的问题

【问题讨论】:

【参考方案1】:

我希望unlist(foolist) 会帮助你。它有一个选项recursive,默认为TRUE

所以unlist(foolist, recursive = FALSE)会返回文档列表,然后你可以通过以下方式组合它们:

do.call(c, unlist(foolist, recursive=FALSE))

do.call 只是将函数c 应用于获得的列表的元素

【讨论】:

还可以考虑使用NCmisc::Unlist() 在第一级之外取消列出。【参考方案2】:

当列表嵌套多次并且列表元素之间的嵌套量不同时,这是一个更通用的解决方案:

 flattenlist <- function(x)  
  morelists <- sapply(x, function(xprime) class(xprime)[1]=="list")
  out <- c(x[!morelists], unlist(x[morelists], recursive=FALSE))
  if(sum(morelists)) 
    Recall(out)
  else
    return(out)
  

【讨论】:

只是为了让这一点更容易理解,我只想指出,在以下情况下使用 class(xprime)[1]=="list") 识别列表是必要的(而不是使用 is.list)您的嵌套对象属于从列表继承的类(即注意 is.list(data.frame(3)) 评估为 TRUE) 还要注意这并没有保留原结构的顺序 可能只是将out &lt;- c( 替换为mapply 语句,该语句将xmorelists 作为参数,然后仅取消列出morelists 为TRUE 的元素 或将前两行替换为一个结合了测试和取消列表的lapply 非常有用:我的用例是map(some_nested_list, flattenlist) %&gt;% bind_rows() 来生成一个小标题。【参考方案3】:

这是另一种适用于我的列表的方法。

df &lt;- as.data.frame(do.call(rbind, lapply(foolist, as.data.frame)))

或者看看 tidyr 中运行良好的新函数。

rectangle a nested list into a tidy tibble

rectangling

    lst <-  list(
      list(
        age = 23,
        gender = "Male",
        city = "Sydney"
      ),
      list(
        age = 21,
        gender = "Female",
        city = "Cairns"
      )
    )
      
    tib <- tibble(lst)  %>% 
      unnest_wider(lst)

df <- as.data.frame(tib)

【讨论】:

感谢分享。 tidyr 包中的unnest_wider 运行良好。您发布的其他代码给了我一条错误消息“match.names(clabs, names(xi)) 中的错误:名称与以前的名称不匹配”-> 我正在使用的数据是作为 JSON 从 Facebook 下载的。它是高度嵌套的。并非列表中的所有列表都一样长。下载文件的数据结构也不同。 @Simone,我认为您应该发布一个简单复制数据的新问题,然后一些人可以尝试帮助您。 SO不喜欢问题中的问题 我did。想指出有“通常”嵌套列表和高度嵌套列表。对于后者,tidyr 包很有用。 --> 因此是评论而不是新问题。

以上是关于如何展平列表列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何展平haskell中的列表列表

当某些列表包含 Null 值时,如何展平列表列?

Python:如何展平每个子列表是一个包含单个浮点数的列表列表[关闭]

如何将 java 映射展平为列表,以便列表交替键和值?

如何展平包含具有不同数量字典的列表的列表? [复制]

如何使用两个列表推导展平嵌套的字符串列表