[英]How to display a list of lists in a nice way
我有一個列表列表,如下所示。
每個列表(例如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)
當我們打印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"
如何將其轉換為這樣的數據幀?
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))
這不僅是一個嵌套list
問題,還是一個嵌套問題。 如果我正確地解釋了事情,那么顏色和價格在一個列表中,而四分之一在另一個列表中這一事實是有意義的。 因此,實際上,您應該研究如何將每個列表的第一個元素轉換為data.frame
,對所有其他元素重復此操作,然后加入結果。 (這是@divibisan和@camille的建議開始起作用的地方...減少問題,使用重復項的代碼,然后合並。)
(事實上,我相信您在每個列表中都不會有兩個以上的元素嚴格來說並不是一個因素。以下是處理1個或多個對象的一般方法,而不僅僅是“總是2個”。)
您的數據:
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"
我們需要做的是通過每個元素列表來分解它。 (我假設這里是對稱的。)讓我們從處理每個元素的第一個元素開始:
total1 <- lapply(total, `[[`, 1)
str(total1)
# List of 3
# $ : chr [1:2] "Color" "Price"
# $ : chr "Price"
# $ : chr "Color"
為了使用雙軌騙局的建議,我們需要知道填充多少。 也就是說,它們必須具有相同的長度。
( maxlen <- max(sapply(total1, function(l) length(unlist(l)))) )
# [1] 2
現在我們填充它們:
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
(您可以在這里開始看到該結構的破裂。) cbind
建議cbind
它們cbind
,但是您想rbind
它們:
do.call(rbind, total1)
# [,1] [,2]
# [1,] "Color" "Price"
# [2,] "Price" NA
# [3,] "Color" NA
現在這是一個matrix
,而不是data.frame
,但這是一個開始。 最后,讓我們開始命名。 讓我們編寫一個函數來完成我們剛剛做的事情,然后在total
每個級別上使用它。
為了做到這一點,我們需要修改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"
因此,盡管作為matrix
,這最后一點幾乎是您所需要的。 從這里開始,命名很容易:
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.