R:purrr查找包含命名变量的列表元素

时间:2019-06-24 22:45:53

标签: r list reference iteration purrr

我有一个变量名称的字符向量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)

2 个答案:

答案 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))