首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R:理解purrr提取函数

R:理解purrr提取函数
EN

Stack Overflow用户
提问于 2019-06-25 04:10:54
回答 1查看 3K关注 0票数 0

这里有一个简单的嵌套列表,包含三个级别,ob级,每个级别包含两个v级列表;v级包含一个或两个s级对象,而s级包含一个字符向量。

代码语言:javascript
复制
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)))

我试图了解如何使用purrr的映射函数按名称提取这个列表的各个级别。

有关提取的帮助文件提供了一个示例,该示例使用列表的名称进行提取,列表的顶层没有名称。在本例中,提取函数跳过顶层,并使用名称在第二层查找元素。

代码语言:javascript
复制
l1 <- list(list(a = 1L), list(a = NULL, b = 2L), list(b = 3L))
l1 %>% map("a", .default = "???")

第二个示例没有名称,并按位置进行索引。然而,同样,这些职位是列表中每个顶级元素中的职位.

代码语言:javascript
复制
l2 <- list(
 list(num = 1:3,     letters[1:3]),
 list(num = 101:103, letters[4:6]),
 list()
)
l2 %>% map(c(2, 2))

在上面的第一个例子中,假设指定了顶层。会发生什么?

代码语言:javascript
复制
l1 <- list(one = list(a = 1L), two = list(a = NULL, b = 2L), three = list(b = 3L))
l1 %>% map("a", .default = "???")

结果没有变化。所以我希望从

代码语言:javascript
复制
map(test_lst, c("v1", "s2"))

同样地跳过顶级名称并返回等效的

代码语言:javascript
复制
lapply(c("ob1", "ob2"), function(X)test_lst[[X]][["v1"]][["s2"]])

[[1]]
[1] "A1" "A2" "A3"

[[2]]
[1] "A9"  "A10" "A11

但事实并非如此。相反,

代码语言:javascript
复制
find_vars <- function(meta){
map_chr(meta, c("v1", "s2")) -> var_vecs
var_vecs
}

find_vars(meta = test_lst)

产生以下错误:

代码语言:javascript
复制
 Error: Result 1 must be a single string, not a character vector of length 3
Call `rlang::last_error()` to see a backtrace 
7. stop(cnd) 
6. abort(message, x = x, expected = expected, actual = actual, what = what, 
    arg = arg, ..., .subclass = c(.subclass, "purrr_error_bad_type")) 
5. stop_bad_type(x, expected, actual = actual, what = what, arg = arg, 
    recycle = recycle, message = message, .subclass = c(.subclass, 
        "purrr_error_bad_vector")) 
4. stop_bad_vector(x, expected_ptype, expected_length, what = what, 
    arg = arg, index = index, ..., recycle = recycle, message = message, 
    .subclass = c(.subclass, "purrr_error_bad_element_vector")) 
3. purrr:::stop_bad_element_vector(c("A1", "A2", "A3"), 1, character(0), 
    1, what = "Result", arg = NULL, recycle = FALSE) 
2. map_chr(meta, c("v1", "s2")) 
1. find_vars(meta = test_lst) 

> rlang::last_error()
<error>
message: Result 1 must be a single string, not a character vector of length 3
class:   `purrr_error_bad_element_vector`
backtrace:
 1. global::find_vars(meta = test_lst)
 3. purrr:::stop_bad_element_vector(...)
 4. purrr:::stop_bad_vector(...)
 5. purrr:::stop_bad_type(...)
Call `rlang::last_trace()` to see the full backtrace
> rlang::last_trace()
    x
 1. +-global::find_vars(meta = test_lst)
 2. | \-purrr::map_chr(meta, c("v1", "s2"))
 3. \-purrr:::stop_bad_element_vector(...)
 4.   \-purrr:::stop_bad_vector(...)
 5.     \-purrr:::stop_bad_type(...)

我想了解:

  • 为什么我会犯错;
  • 这个错误意味着什么?
  • 如何使用lapply获得类似于上面的purrr结果的结果。
EN

回答 1

Stack Overflow用户

发布于 2019-06-25 04:15:53

如果我们想要提取,那么使用pluck

代码语言:javascript
复制
pluck(test_lst, c("v1", "s2"))

对于errormap_chr希望根据文档返回一个字符vector

map_lgl()、map_int()、map_dbl()和map_chr()分别返回指定类型的原子向量(或死试)。

但是这里的输出是‘`list’。请考虑以下示例

代码语言:javascript
复制
map(test_lst, c("v1", "s2")) %>%
           map_chr(toString)
#         ob1            ob2 
#"A1, A2, A3" "A9, A10, A11" 

在将组件提取为list之后,我们将元素提取为map_chr中的单个字符串,现在它将其扁平化为vector。但是,如果其意图是以vector的形式返回所有内容,它将不允许

代码语言:javascript
复制
map(test_lst, c("v1", "s2")) %>% 
        map_chr(I)

错误:结果1必须是单个字符串,而不是类AsIs的向量,长度为3的调用rlang::last_error()才能看到回溯

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56746726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档