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

时间:2011-08-02 03:57:15

标签: r list extract

例如,如何在下面的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

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

5 个答案:

答案 0 :(得分:17)

您可以使用sapply

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

答案 1 :(得分:7)

根据您提供的数据结构,我会使用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()

或者 - 如果您首先可以灵活地存储数据,那么将其存储为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))

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

答案 2 :(得分:1)

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

输出:

  

[1] 23 35 20 31 26

答案 3 :(得分:0)

除了apply - 家庭之外,@ Hadley的purrr package提供map_ - 这类工作的功能。

(与apply家庭有一些差异,例如here讨论过。)

OPs示例:

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

答案 4 :(得分:0)

尽管这个问题已经很老了,但我还是想分享一下我的解决方法。当然可以将sapply用作 建议tflutre。但是我发现通过使用unlist函数可以更直观:

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

请注意2 * length(people)中乘以 2 poeple列表中存储了两个元素。通过编写length(people[[1]]) * length(people)

可以使它更通用。

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

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

,然后使用seq命令按其他元素进行切片。