根据您的示例,我想您有许多 vecs,您希望将它们全部设置在一个基于数据框的部分公共部分的名称中。
例如,你有这三个vecs:
vec1 <- setNames(c(1,2,3), c("BB745","456AA", "123CC3"))
vec2 <- setNames(c(3,2,1), c("BB345","113AA", "543CC6"))
vec3 <- setNames(c(2,1,3), c("BB567","AA111", "345CC8"))
并且您想根据以下字符串的存在将它们设置在一起:
nn <- c("AA", "BB", "CC")
在这种情况下,我建议您按照以下方式进行。
在一个列表中设置您的vec:
l <- list(vec1,vec2,vec3)
然后使用这一行:
library(purrr)
library(stringr)
nn_clps <- paste(nn, collapse = "|")
map_dfr(l, ~setNames(., str_extract(names(.), nn_clps))) %>% select(all_of(nn))
#> # A tibble: 3 x 3
#> AA BB CC
#> <dbl> <dbl> <dbl>
#> 1 2 1 3
#> 2 2 3 1
#> 3 1 2 3
它有什么作用?
- 我们使用来自
purrr 包的map 对每个向量应用一个函数
- 这样,我们每次取一个
vec,并从名称中提取nn中的字符串:所以AA、BB或CC之一。为此,我们使用 stringr 包中的 str_extract。
- 然后我们用我们提取的字符串重命名每个向量。我们使用
setNames
- 最后,所有字符串都设置在一个唯一的数据帧中。这是由
map_dfr 执行的,其行为类似于map,但将输出定义为一个唯一的数据帧(dfr 代表将行绑定到数据帧)。
- 要按预期顺序设置列,有多种方法。一种可能是来自
dplyr 包中的select。 all_of 只是翻译从 select 可以理解的名称中的字符串。同样[nn] 而不是 %>% select(all_of(nn)) 也可以正常工作。像这样:
map_dfr(l, ~setNames(., str_extract(names(.), nn_clps)))[nn]
查看?map 以了解. 和~ 的作用。
简而言之:创建匿名函数需要~,.是匿名函数中x的占位符。
所有代码放在一起。
我稍微修改了它以按照您想要的顺序设置列。
vec1 <- setNames(c(1,2,3), c("BB745","456AA","123CC3"))
vec2 <- setNames(c(3,2,1), c("BB345","113AA","543CC6"))
vec3 <- setNames(c(2,1,3), c("BB567","AA111","345CC8"))
nn <- c("AA", "BB", "CC")
l <- list(vec1,vec2,vec3)
library(purrr)
library(stringr)
library(dplyr)
nn_clps <- paste(nn, collapse = "|")
map_dfr(l, ~setNames(., str_extract(names(.), nn_clps))) %>% select(all_of(nn))