简体   繁体   English

如何以一种不错的方式显示列表列表

[英]How to display a list of lists in a nice way

I have a list of lists, such as below. 我有一个列表列表,如下所示。

Each list (eg list1, list2, list3) has two attributes: Variable and Time 每个列表(例如list1,list2,list3)都有两个属性:Variable和Time

list1 <- list(c("Color", "Price"), "Quarter")
list2 <- list(c("Price"), "Month")
list3 <- list(c("Color"), "Month")
total <- list(list1, list2, list3)

when we print total , we'll see: 当我们打印total ,我们将看到:

[[1]]
[[1]][[1]]
[1] "Color" "Price"

[[1]][[2]]
[1] "Quarter"


[[2]]
[[2]][[1]]
[1] "Price"

[[2]][[2]]
[1] "Month"


[[3]]
[[3]][[1]]
[1] "Color"

[[3]][[2]]
[1] "Month"

How can I turn it into a data frame such as this one? 如何将其转换为这样的数据帧?

EDIT: I am able to accomplish it using this code. Any better suggestion is appreciated!

  num <- length(total)
  max      <- 0
  for(i in 1:num) {
    if(length(total[[i]][1]) > max) {
      max <- length(total[[i]])
    }
  }

  for(i in 1:num) {
    length(total[[i]][[1]]) <- max
    for(j in 1:max) {
      if(is.null(total[[i]][[1]][[j]])) {
        total[[i]][[1]][[j]] <- " "
      }
    }
  }

  df <- data.frame(matrix(unlist(total), nrow=num, byrow=T))

This isn't just a nested- list problem, it's a nested problem. 这不仅是一个嵌套list问题,还是一个嵌套问题。 If I'm interpretting things correctly, the fact that Color and Price are in one list and Quarter is in another is meaningful. 如果我正确地解释了事情,那么颜色和价格在一个列表中,而四分之一在另一个列表中这一事实是有意义的。 So really, you should be looking at how to turn the first element of each list into a data.frame , repeat for all other elements, then join the results. 因此,实际上,您应该研究如何将每个列表的第一个元素转换为data.frame ,对所有其他元素重复此操作,然后加入结果。 (This is where @divibisan's and @camille's suggestions come into play ... reduce the problem, use the duplicates' code, then combine.) (这是@divibisan和@camille的建议开始起作用的地方...减少问题,使用重复项的代码,然后合并。)

(The fact that I believe you will never have more than two elems in each list is not strictly a factor. Below is a general way of handling 1-or-more, not just "always 2".) (事实上​​,我相信您在每个列表中都不会有两个以上的元素严格来说并不是一个因素。以下是处理1个或多个对象的一般方法,而不仅仅是“总是2个”。)

Your data: 您的数据:

str(total)
# List of 3
#  $ :List of 2
#   ..$ : chr [1:2] "Color" "Price"
#   ..$ : chr "Quarter"
#  $ :List of 2
#   ..$ : chr "Price"
#   ..$ : chr "Month"
#  $ :List of 2
#   ..$ : chr "Color"
#   ..$ : chr "Month"

What we need to do is break this down by element-of-each-list. 我们需要做的是通过每个元素列表来分解它。 (I'm assuming that there will be symmetry here.) Let's start by just working on the first elem of each: (我假设这里是对称的。)让我们从处理每个元素的第一个元素开始:

total1 <- lapply(total, `[[`, 1)
str(total1)
# List of 3
#  $ : chr [1:2] "Color" "Price"
#  $ : chr "Price"
#  $ : chr "Color"

In order to use the suggestions from the dupes, we need to know how much to pad them. 为了使用双轨骗局的建议,我们需要知道填充多少。 That is, they need to be the same length. 也就是说,它们必须具有相同的长度。

( maxlen <- max(sapply(total1, function(l) length(unlist(l)))) )
# [1] 2

Now we pad them: 现在我们填充它们:

total1 <- lapply(total1, function(l) { length(l) <- maxlen; l; })
str(total1)
# List of 3
#  $ : chr [1:2] "Color" "Price"
#  $ : chr [1:2] "Price" NA
#  $ : chr [1:2] "Color" NA

(You can start to see the structure break out here.) The dupes suggested cbind ing them, but you want to rbind them: (您可以在这里开始看到该结构的破裂。) cbind建议cbind它们cbind ,但是您想rbind它们:

do.call(rbind, total1)
#      [,1]    [,2]   
# [1,] "Color" "Price"
# [2,] "Price" NA     
# [3,] "Color" NA     

Now this is a matrix , not a data.frame , but it's a start. 现在这是一个matrix ,而不是data.frame ,但这是一个开始。 Let's work with naming at the end. 最后,让我们开始命名。 Let's write a function to do what we just did, and then we'll use it on each level of total . 让我们编写一个函数来完成我们刚刚做的事情,然后在total每个级别上使用它。

In order to do this, though, we need to modify total , so that the new first element has all first elements, new second has all seconds, etc. 为了做到这一点,我们需要修改total ,以便新的第一个元素具有所有第一个元素,新的第二个元素具有所有秒,依此类推。

newtotal <- lapply(seq_len(max(sapply(total, length))), function(i) lapply(total, `[[`, i))
str(newtotal)
# List of 2
#  $ :List of 3
#   ..$ : chr [1:2] "Color" "Price"
#   ..$ : chr "Price"
#   ..$ : chr "Color"
#  $ :List of 3
#   ..$ : chr "Quarter"
#   ..$ : chr "Month"
#   ..$ : chr "Month"
m <- do.call(cbind, lapply(newtotal, func))
m
#      [,1]    [,2]    [,3]     
# [1,] "Color" "Price" "Quarter"
# [2,] "Price" NA      "Month"  
# [3,] "Color" NA      "Month"  

So this last point is pretty much what you need, though as a matrix . 因此,尽管作为matrix ,这最后一点几乎是您所需要的。 From here, it's easy enough to name things: 从这里开始,命名很容易:

m <- do.call(cbind, lapply(newtotal, func))
colnames(m) <- c(paste0("Var", seq_len(ncol(m)-1L)), "Time")
df <- as.data.frame(m)
df$List <- paste0('List', seq_len(nrow(df)))
df
#    Var1  Var2    Time  List
# 1 Color Price Quarter List1
# 2 Price  <NA>   Month List2
# 3 Color  <NA>   Month List3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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