使用行列索引对从数据框中的不同列中选择值的 Tidyverse 方法
Tidyverse approach to selecting values from different columns in a dataframe with row-column index pairs
在 R 中,我有一个字符向量 v
,其值是数据帧 rain
的 colnames(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)))]
在 R 中,我有一个字符向量 v
,其值是数据帧 rain
的 colnames(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)))]