使用行列索引对从数据框中的不同列中选择值的 Tidyverse 方法

Tidyverse approach to selecting values from different columns in a dataframe with row-column index pairs

在 R 中,我有一个字符向量 v,其值是数据帧 raincolnames(rain) 的所有元素。我想使用 v 创建一个新向量 chosen,其值满足 chosen[i] == rain[i, v[i]] 而无需诉诸循环,最好使用 tidyverse 方法。

例如,如果我有:

library(tidyverse)
rain <- tibble(ceres = c(0, 1, 0, 1.5, 3),
               mond = c(0, 0, 0.5, 0, 0),
               els = c(1, 2, 1, 0, 1))

v <- c("els", "ceres", "els", "mond", "ceres")

我希望在选择中返回:

> chosen
# els ceres   els  mond ceres 
#    1     1     1     0     3

你的意思是这样的吗?

> mapply(`[`, rain[v], seq_along(v))
  els ceres   els  mond ceres
    1     1     1     0     3

> mapply(function(p, q) rain[[p]][q], v, seq_along(v))
  els ceres   els  mond ceres
    1     1     1     0     3

> setNames(as.matrix(rain)[cbind(seq_along(v), match(v, names(rain)))], v)
  els ceres   els  mond ceres
    1     1     1     0     3

我认为这可能是一个 XY problem,我至少从未遇到过需要像那样索引数据框。我怀疑您可以对数据进行不同的编码,但如果不是这样,您可以像这样进行索引

enframe(v, name = "i", value = "j") %>% 
  rowwise() %>% 
  summarise(
    name = j, value = rain[[i, j]]
  ) %>% 
  deframe()
#>   els ceres   els  mond ceres 
#>     1     1     1     0     3

reprex package (v1.0.0)

于 2021-08-09 创建

您还可以使用 purrr

中的 map2 函数
map2_dbl(set_names(v), seq_along(v), ~rain[[.y, .x]])

#>   els ceres   els  mond ceres 
#>     1     1     1     0     3

你可以

rain %>%
  mutate(id = row_number()) %>%
  pivot_longer(-id) %>%
  inner_join(tibble(id = seq_along(v), name = v)) 

哪个returns

# A tibble: 5 x 3
     id name  value
  <int> <chr> <dbl>
1     1 els       1
2     2 ceres     1
3     3 els       1
4     4 mond      0
5     5 ceres     3

添加

pull(value, name)

returns 命名向量

#>  els ceres   els  mond ceres 
#>    1     1     1     0     3 

已经有很多答案了,但只是为了表明在基 R 中使用矩阵索引非常简单

m.rain = as.matrix(rain, rownames.force =T)
m.rain[cbind(seq_along(v), v)]

或者,类似的:

as.matrix(rain)[cbind(seq_along(v), match(v, names(rain)))]