【问题标题】:Access vectors in a list with an array of indices in R使用 R 中的索引数组访问列表中的向量
【发布时间】:2020-05-10 21:05:43
【问题描述】:

我有一个包含 3 个向量的列表,例如:

> test_list
[[1]]
[1] "a" "b"

[[2]]
[1] "c" "d" "e"

[[3]]
[1] "f" "g"

我想使用包含向量索引的数组来访问这些向量的元素,例如:

> indices
     [,1] [,2] [,3]
[1,]    1    3    2
[2,]    2    2    2

这是所需的输出:

     [,1] [,2] [,3]
[1,] "a"  "e"  "g"
[2,] "b"  "d"  "g"

我找到了以下方法:

test_list <- list(c("a", "b"), c("c", "d", "e"), c("f", "g"))
indices <- matrix(c(1, 3, 2, 2, 2, 2), nrow = 2, ncol = 3, byrow = TRUE)
t(apply(indices, 1, function(row){mapply(`[[`, test_list, row)}))

有没有更干净、更惯用的方式?

【问题讨论】:

  • 可能是mapply("[",test_list,as.data.frame(indices))
  • 我可能会写成sapply(seq_along(test_list), function (i) test_list[[i]][indices[, i]]),但实际上更长。但它 (a) 只使用一个高阶函数,即它不嵌套循环,它 (b) 不双重转置隐式矩阵,因此它在概念上更简单。 (实际上我会使用lapply 而不是容易出错的sapply,然后将结果显式转换为矩阵,但这甚至更长)。

标签: r arrays list vector indexing


【解决方案1】:

涉及purrr 的一个选项可能是:

map2(.x = test_list, 
     .y = asplit(indices, 2),
     ~ .x[.y]) %>%
 transpose()

[[1]]
[1] "a" "e" "g"

[[2]]
[1] "b" "d" "g"

或者使用@nicola 提供的评论中的想法的base R 解决方案:

mapply(`[`, test_list, asplit(indices, 2))

【讨论】:

  • 我强烈建议在 R 对象名称中使用反引号而不是字符串引号——R 允许的事实完全是愚蠢的,我们应该尽力假装不存在。也就是说,非常好的答案。
  • @Konrad Rudolph 很高兴收到你的评论,自从我来到这个网站以来,我从你的反馈中学到了很多 :)
【解决方案2】:

base R 中的另一个选项

out <- do.call(rbind, lapply(test_list, `length<-`, max(lengths(test_list))))   
`dim<-`(out[cbind(c(col(indices)), c(indices))], c(2,  3))
#    [,1] [,2] [,3]
#[1,] "a"  "e"  "g" 
#[2,] "b"  "d"  "g" 

【讨论】:

    猜你喜欢
    • 2018-07-26
    • 2016-02-03
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多