我有一个变量名称的字符向量nms
,它们全部出现在多个文件中的至少一个中。如果一个变量存在于多个文件中,则值将相同。
我有一个命名列表test_lst
,其中顶级名称是文件的名称。列表的子列表包括文件中变量名称的向量。
我想使用purrr遍历test_lst
并找到包含每个变量的第一个文件,并返回一个命名列表,其中名称是文件名,每个元素是{中的变量的向量该文件中存在的{1}}。我想按名称而不是按位置索引子列表。
这似乎应该很容易,而且我不知道为什么我不能使它起作用。
数据:
nms
无效代码:
test_lst <- list(ob1 = list(v1 = list(s1 = "X", s2 = paste0("A", 1:3)), v2 = paste0("A", 4:8)),
ob2 = list(v1 = list(s1 = "X", s2 = paste0("A", 9:11)), v2 = paste0("A", 12:16)))
nms <- c (paste0("A", 1:2), paste0("A", 9:10))
所需的输出,列表:
find_vars <- function(var_names, meta){
map_chr(meta, c("v1", "s2")) -> var_vecs
names(var_vecs)<- names(meta)
map_chr(var_vecs, var_names %in% .) -> out
names(out) <- names(var_vecs)
out
}
find_vars(var_names = nms, meta = test_lst)
答案 0 :(得分:1)
我们可以使用modify_depth
library(tidyverse)
modify_depth(test_lst, 2, ~ enframe(.x) %>%
select(value) %>%
unnest %>%
filter(value %in% nms)) %>%
flatten %>%
keep(~ nrow(.x) > 0) %>%
map(~ .x %>%
pull(value)) %>%
set_names(names(test_lst))
#$ob1
#[1] "A1" "A2"
#$ob2
#[1] "A9" "A10"
或者我们可以先enframe
,然后遍历“值”列以对元素进行子集化
enframe(test_lst) %>%
unnest %>%
mutate(value = map(value, ~ intersect(nms, unlist(.x)))) %>%
unnest %>%
deframe %>%
split(names(.))
或者使用与之前intersect
相同的符号
map(test_lst, ~ intersect(nms, unlist(.x)))
或另一个选项是melt
library(reshape2)
melt(test_lst) %>%
select(L1, value) %>%
group_by(L1) %>%
filter(value %in% nms) %>%
{split(as.character(.$value), .$L1)}
答案 1 :(得分:1)
我们可以unlist
test_lst
的所有值,并使用intersect
找出通用值
lapply(test_lst, function(x) intersect(unlist(x), nms))
#$ob1
#[1] "A1" "A2"
#$ob2
#[1] "A9" "A10"
如果您想使用purrr
,我们可以将lapply
更改为map
purrr::map(test_lst, ~intersect(unlist(.), nms))