gpt4 book ai didi

r - 如何获取列表中元素的位置?

转载 作者:行者123 更新时间:2023-12-03 23:26:01 27 4
gpt4 key购买 nike

给定一个列表变量,我想要一个每个元素位置的数据框。对于一个简单的非嵌套列表,它看起来很简单。

例如,这里有一个字符向量列表。

l <- replicate(
10,
sample(letters, rpois(1, 2), replace = TRUE),
simplify = FALSE
)
l看起来像这样:
[[1]]
[1] "m"

[[2]]
[1] "o" "r"

[[3]]
[1] "g" "m"
# etc.

要获取位置的数据框,我可以使用:
d <- data.frame(
value = unlist(l),
i = rep(seq_len(length(l)), lengths(l)),
j = rapply(l, seq_along, how = "unlist"),
stringsAsFactors = FALSE
)
head(d)
## value i j
## 1 m 1 1
## 2 o 2 1
## 3 r 2 2
## 4 g 3 1
## 5 m 3 2
## 6 w 4 1

给定一个更棘手的嵌套列表,例如:
l2 <- list(
"a",
list("b", list("c", c("d", "a", "e"))),
character(),
c("e", "b"),
list("e"),
list(list(list("f")))
)

这并不容易概括。

我期望这个例子的输出是:
data.frame(
value = c("a", "b", "c", "d", "a", "e", "e", "b", "e", "f"),
i1 = c(1, 2, 2, 2, 2, 2, 4, 4, 5, 6),
i2 = c(1, 1, 2, 2, 2, 2, 1, 2, 1, 1),
i3 = c(NA, 1, 1, 2, 2, 2, NA, NA, 1, 1),
i4 = c(NA, NA, 1, 1, 2, 3, NA, NA, NA, 1),
i5 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 1)
)

如何获取嵌套列表的位置数据框?

最佳答案

这是一种产生与您展示的输出略有不同的输出的方法,但它会在进一步的道路上有用。

f <- function(l) {
names(l) <- seq_along(l)
lapply(l, function(x) {
x <- setNames(x, seq_along(x))
if(is.list(x)) f(x) else x
})
}

功能 f简单地(递归地)遍历给定列表的所有级别并命名它的元素 1,2,...,n哪里 n是(子)列表的长度。然后,我们可以利用 unlist 的事实。有一个 use.names参数是 TRUE默认情况下,在命名列表上使用时有效(这就是为什么我们必须先使用 f 来命名列表)。

对于嵌套列表 l2它返回:
unlist(f(l2))
# 1.1 2.1.1 2.2.1.1 2.2.2.1 2.2.2.2 2.2.2.3 4.1 4.2 5.1.1 6.1.1.1.1
# "a" "b" "c" "d" "a" "e" "e" "b" "e" "f"

现在,为了返回一个 data.frame正如问题中所要求的那样,我会这样做:
g <- function(l) {
vec <- unlist(f(l))
n <- max(lengths(strsplit(names(vec), ".", fixed=TRUE)))
require(tidyr)
data.frame(
value = unname(vec),
i = names(vec)
) %>%
separate(i, paste0("i", 1:n), sep = "\\.", fill = "right", convert = TRUE)
}

并像这样应用它:
g(l2)
# value i1 i2 i3 i4 i5
#1 a 1 1 NA NA NA
#2 b 2 1 1 NA NA
#3 c 2 2 1 1 NA
#4 d 2 2 2 1 NA
#5 a 2 2 2 2 NA
#6 e 2 2 2 3 NA
#7 e 4 1 NA NA NA
#8 b 4 2 NA NA NA
#9 e 5 1 1 NA NA
#10 f 6 1 1 1 1
g的改进版,由@AnandaMahto 提供(谢谢!),将使用 data.table :
g <- function(inlist) {
require(data.table)
temp <- unlist(f(inlist))
setDT(tstrsplit(names(temp), ".", fixed = TRUE))[, value := unname(temp)][]
}

编辑 (学分转到@TylerRinkler - 谢谢!)

这样做的好处是可以轻松转换为 数据树对象然后可以转换为许多其他数据类型。稍微修改一下 g :
g <- function(l) {
vec <- unlist(f(l))
n <- max(lengths(strsplit(names(vec), ".", fixed=TRUE)))
require(tidyr)
data.frame(
i = names(vec),
value = unname(vec)
) %>%
separate(i, paste0("i", 1:n), sep = "\\.", fill = "right", convert = TRUE)
}

library(data.tree)

x <- data.frame(top=".", g(l2))
x$pathString <- apply(x, 1, function(x) paste(trimws(na.omit(x)), collapse="/"))
mytree <- data.tree::as.Node(x)

mytree
# levelName
#1 .
#2 ¦--1
#3 ¦ °--1
#4 ¦ °--a
#5 ¦--2
#6 ¦ ¦--1
#7 ¦ ¦ °--1
#8 ¦ ¦ °--b
#9 ¦ °--2
#10 ¦ ¦--1
#11 ¦ ¦ °--1
#12 ¦ ¦ °--c
#13 ¦ °--2
#14 ¦ ¦--1
#15 ¦ ¦ °--d
#16 ¦ ¦--2
#17 ¦ ¦ °--a
#18 ¦ °--3
#19 ¦ °--e
#20 ¦--4
#21 ¦ ¦--1
#22 ¦ ¦ °--e
#23 ¦ °--2
#24 ¦ °--b
#25 ¦--5
#26 ¦ °--1
#27 ¦ °--1
#28 ¦ °--e
#29 °--6
#30 °--1
#31 °--1
#32 °--1
#33 °--1
#34 °--f

并产生一个很好的情节:
plot(mytree)

pic

呈现数据的其他形式:
as.list(mytree)
ToDataFrameTypeCol(mytree)

更多关于转换 数据树类型:

https://cran.r-project.org/web/packages/data.tree/vignettes/data.tree.html#tree-conversion
http://www.r-bloggers.com/how-to-convert-an-r-data-tree-to-json/

关于r - 如何获取列表中元素的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35456914/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com