我正在使用purrr
做一些工作,并希望针对此问题提供完整的管道解决方案。我正在使用sapply
,但认为这不是最佳解决方案。它适用于这个小型演示,但在实际数据中,ch1的长度大于50,000,而ch2大于100。
library(stringr)
library(purrr)
ch1 <- c("something very interesting or perhaps it is not", "lions, tigers and elephants are safari animals", "once upon a time there was a big castle",
"I have not seen anything as a big as elephants")
ch2 <- c("big", "not")
对于ch2
的每个元素,我们希望看到它们是否出现在ch1
的每个元素中。
str_detect(ch1, ch2[1]) # FALSE FALSE TRUE TRUE
str_detect(ch1, ch2[2]) # TRUE FALSE FALSE TRUE
尝试使用purrr
在所有ch1
上应用函数:
ch1 %>% map_lgl(str_detect(., ch2[2])) # TRUE FALSE FALSE TRUE
我可以使用ch2
sapply
执行此操作
sapply(ch2, function(x) ch1 %>% map_lgl(str_detect(., x)))
big not
[1,] FALSE TRUE
[2,] FALSE FALSE
[3,] TRUE FALSE
[4,] TRUE TRUE
然而,对于真实的数据集,我认为必须有一个完整的purrr
解决方案 - 比如使用map2
,即使用两个列表 - 但很明显它不能成为特定的一个它需要相同长度的列表。
答案 0 :(得分:1)
以下内容在大型数据集上可能比帖子中的代码快一些,会返回一个向量列表。
library(stringr)
library(purrr
lst <- ch2 %>% split(ch2) %>%
map( ~ str_detect(ch1, .x))
要返回矩阵,您可以使用以下内容:
mat <- ch2 %>% split(ch2) %>%
map( ~ str_detect(ch1, .x)) %>%
map_call(cbind)
但是,由于map_call
只是do.call
的一个瘦包装,因此可能有点慢。如果您可以使用dplyr
并使用data.frame
作为结果,则可能会更快一些:
library(dplyr)
df <- ch2 %>% split(ch2) %>%
map( ~ str_detect(ch1, .x)) %>%
as_data_frame()
<强>加强>
以下是使用map2
# solution using map2
mat2 <- ch1 %>% list %>%
map2(ch2, ~ str_detect(.x, .y)) %>%
map_call(cbind)
colnames(mat2) <- ch2
产生具有列名称的矩阵的最直接的可能是:
names(ch2) <- ch2
mat3 <- ch2 %>% map( ~ str_detect(ch1, .x)) %>%
map_call(cbind)