2011-08-02 60 views
8

例如,如何获取每个在下面的列表people向量和每个人的年龄:如何从R中的统一列表中提取值?

> 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 

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

回答

15

您可以使用sapply

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

* facepalms *我完全无视*适用的东西...非常有帮助。谢谢。 – c00kiemonster

6

给你提供的数据结构,我会用sapply

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

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

但是,你会发现,这样做的结果是字符数据。

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

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

或者 - 如果你有灵活性,对你如何存储在首位的数据,它可能是有意义的,将其存储为data.frame个清单:

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

如果你要去那么远,你可能还需要考虑您的所有数据的单一data.frame:

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

可能有一些其他的原因,你没有考虑这种做法在第一时间围绕虽然...

+1

是的,在这个简单的例子中,数据帧可能更好。但“真实”的例子要复杂得多,所以列表更合适。无论如何感谢 – c00kiemonster

+0

@ c00kie - 这就是我的想法,但有时很容易忽略看似明显的:) – Chase

+6

+1有关R-ish的建议,而不是Pythonic的数据结构。另外,仅仅因为我认为它很漂亮:'sapply(人,“[”,2)'。 – joran

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

输出:

[1] 23 35 20 31 26

0

可选地到apply -family有@哈德利的purrr package它提供了map_ -functions对于这种工作。

(有到apply例如here - 家庭讨论的一些区别。)

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) 

sapply方法:

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

而且map方法:

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

当然,他们是相同的:

identical(ages_sapply, ages_map) 
[1] TRUE