例如,如何在下面的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列表的理解或具有同样效果的东西?
答案 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
命令按其他元素进行切片。