使用 purrr 处理顺序任务

handling sequential tasks with purrr

我想获取对象列表并从所有对象中构建一个对象。实际用例是将多个 Seurat 对象组合成一个对象。目前我使用 for 循环,但是,我很好奇我是否可以使用 purrr::map。为了使问题更简单,让我们连接列表的一部分。尽量不要对结果太可爱,因为我真正的问题更难(一个更复杂的函数)。

w1 = list(a="first",b="This")
w2 = list(a="second",b="is")
w3 = list(a="third",b="the")
w4 = list(a="fourth",b="desired results")

期望的结果是 "This is the desired results"。

list(w1,w2,w3,w4) %>% map(paste,.$b," ")

给予

[[1]] [1] "This "

[[2]] [1] "is "

[[3]] [1] "the "

[[4]] [1] "desired result "

我想保存上一次迭代的结果并将其作为参数添加到函数中。

基本上我想用功能替换以下行。

y=NULL;for (x in list(w1,w2,w3,w4)){ y=ifelse(is.null(y),x$b,paste0(y," ",x$b))}
#y
#"This is the desired result"
library(purrr)

list(w1, w2, w3, w4) %>% 
  accumulate(~paste(.x, .y[2][[1]]), .init = '') %>% 
  tail(1) %>% 
  substr(2, nchar(.))

# [1] "This is the desired results"

在 Base R 中 do.calllapply

do.call(paste, lapply(list(w1,w2,w3,w4), `[[`, "b"))

# [1] "This is the desired results"

我建议使用 purrr

list(w1,w2,w3,w4) %>% 
  map_chr("b") %>% 
  paste(collapse=" ")

我们可以将一个字符串传递到 map() 到 return 只是那个命名元素,并且由于我们只需要字符值,我们可以使用 map_chr 只得到一个向量字符值而不是列表。最后只需将其通过管道传输到 paste(collapse=) 即可将其变成一个字符串。

但更一般地,如果你想逐步折叠,你可以使用reduce

list(w1, w2, w3, w4) %>% 
  map_chr("b") %>%
  reduce(~paste(.x, .y))