list 如何从 R 中的统一列表中提取值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6907102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 01:41:51  来源:igfitidea点击:

How do I extract values from uniform list in R?

rlistextract

提问by c00kiemonster

For example, how do I get a vector of each and every person's age in the list peoplebelow:

例如,我如何获得以下列表people中每个人年龄的向量:

> people = vector("list", 5)
> people[[1]] = c(name="Paul", age=23)
> people[[2]] = c(name="Peter", age=35)
> people[[3]] = c(name="Sam", age=20)
> people[[4]] = c(name="Lyle", age=31)
> people[[5]] = c(name="Fred", age=26)
> ages = ???
> ages
[1] 23 35 20 31 26

Is there an equivalent of a Python list comprehension or something to the same effect?

是否有等效于 Python 列表理解或具有相同效果的东西?

回答by tflutre

You can use sapply:

您可以使用sapply

> sapply(people, function(x){as.numeric(x[2])})
[1] 23 35 20 31 26

回答by Chase

Given the data structure you provided, I would use sapply:

鉴于您提供的数据结构,我会使用sapply

sapply(people, function(x) x[2])

> sapply(people, function(x) x[2])
 age  age  age  age  age 
"23" "35" "20" "31" "26" 

However, you'll notice that the results of this are character data.

但是,您会注意到此结果是字符数据。

> class(people[[1]])
[1] "character"

One approach would be to coerce to as.numeric()or as.integer()in the call to sapply.

一种方法是强制as.numeric()as.integer()调用 sapply。

Alternatively - if you have flexibility over how you store the data in the first place, it may make sense to store it as a list of data.frames:

或者 - 如果您首先对如何存储数据具有灵活性,则将其存储为data.frames列表可能是有意义的:

people = vector("list", 5)
people[[1]] = data.frame(name="Paul", age=23)
people[[2]] = data.frame(name="Peter", age=35)
...

If you are going to go that far, you may also want to consider a single data.frame for all of your data:

如果你打算走那么远,你可能还想为你的所有数据考虑一个单一的 data.frame:

people2 <- data.frame(name = c("Paul", "Peter", "Sam", "Lyle", "Fred")
                      , age = c(23,35,20,31, 26))

There may be some other reason why you didn't consider this approach the first time around though...

不过,您第一次没有考虑这种方法可能还有其他一些原因......

回答by PeterVermont

ages <- sapply(1:length(people), function(i) as.numeric(people[[i]][[2]]))
ages

Output:

输出:

[1] 23 35 20 31 26

[1] 23 35 20 31 26

回答by symbolrush

Alternatively to the apply-family there's @Hadley's purrrpackagewhich offers the map_-functions for this kind of job.

除了apply-family 之外,还有@Hadley's purrrpackage,它map_为这种工作提供了-functions。

(There's a few differences to the apply-family discussed for example here.)

apply例如这里讨论的-family有一些差异。)

OPs example:

OP示例:

people = vector("list", 5)
people[[1]] = c(name="Paul", age=23)
people[[2]] = c(name="Peter", age=35)
people[[3]] = c(name="Sam", age=20)
people[[4]] = c(name="Lyle", age=31)
people[[5]] = c(name="Fred", age=26)

The sapplyapproach:

sapply方法:

ages_sapply <- sapply(people, function(x){as.numeric(x[2])})
print(ages_sapply)
[1] 23 35 20 31 26

And the mapapproach:

map方法:

ages_map <- purrr::map_dbl(people, function(x){as.numeric(x[2])})
print(ages_map)
[1] 23 35 20 31 26

Of course they are identical:

当然,它们是相同的:

identical(ages_sapply, ages_map)
[1] TRUE

回答by CermakM

Though this question is pretty old, I'd like to share my approach to this. It is certainly possible to do with the sapplyas tflutresuggested. But I find it more intuitive by using the unlistfunction:

虽然这个问题已经很老了,但我想分享我对此的方法。当然可以sapply按照 tflutre 的建议进行处理。但我发现使用该unlist函数更直观:

> ages <- unlist(people, use.names = F)[seq(2, 2 * length(people), 2)]
> ages
[1] "23" "35" "20" "31" "26"

NOTE the multiplication by twoin 2 * length(people), there are two elements stored in the poeplelist. This can be made more generic by writing length(people[[1]]) * length(people)

注意把乘22 * length(people),还有存储在这两个元素poeple列表。这可以通过编写更通用length(people[[1]]) * length(people)

Here unlist(people, use.names = F)yields

这里unlist(people, use.names = F)产量

[1] "Paul"  "23"    "Peter" "35"    "Sam"   "20"    "Lyle"  "31"    "Fred" 
[10] "26" 

and we slice that by every other element using seqcommand.

我们使用seq命令将其按每个其他元素进行切片。