Reputation: 1533
This must be similar to what described here
https://github.com/tidyverse/purrr/issues/179
but I am banging my head against the wall.
Consider the snippet
library(tidyverse)
library(stringr)
library(stringi)
remove_short_words <- function(x, n){
mypattern <- paste("\\w{", n, ",}", sep="")
x2 <- paste(str_extract_all(x, mypattern)[[1]], collapse=' ')
}
shopping_list <- c("apples x4", "bag of flour", "bag of sugar", "milk x2")
dd<-map2(shopping_list, 4, function(x,y) remove_short_words(x,y))
ff<-map2_df(shopping_list, 4, function(x,y) remove_short_words(x,y))
map2 works like a charm, but map2_df throws an error
Error: Argument 1 must have names
Any idea about how to fix this? Thanks!
#I add what works for me. I use an auxiliary function which I plug into map
remove_short_words_aux <- function(x, n){
mypattern <- paste("\\w{", n, ",}", sep="")
x2 <- paste(str_extract_all(x, mypattern)[[1]], collapse=' ')
}
remove_short_words <- function(x,n){
res<-map(x, function(x) remove_short_words_aux(x,n)) %>%
unlist %>%
tibble::enframe(name = NULL)
}
> nn<-remove_short_words(shopping_list,5)
> nn
# A tibble: 4 x 1
value
<chr>
1 "apples"
2 "flour"
3 "sugar"
4 ""
Upvotes: 0
Views: 1609
Reputation: 388982
First I don't think you should use map2
here since n
is fixed and is not changing so using map
would be appropriate.
library(tidyverse)
remove_short_words <- function(x, n){
mypattern <- paste("\\w{", n, ",}", sep="")
paste(str_extract_all(x, mypattern)[[1]], collapse=' ')
}
shopping_list <- c("apples x4", "bag of flour", "bag of sugar", "milk x2")
map(shopping_list, remove_short_words, 4)
#[[1]]
#[1] "apples"
#[[2]]
#[1] "flour"
#[[3]]
#[1] "sugar"
#[[4]]
#[1] "milk"
Note that the output is a list of characters and if you need to combine this to one column dataframe you have two options.
map_chr
-tibble(val = map_chr(shopping_list, remove_short_words, 4))
# val
# <chr>
#1 apples
#2 flour
#3 sugar
#4 milk
map_df
-remove_short_words <- function(x, n){
mypattern <- paste("\\w{", n, ",}", sep="")
tibble(val = paste(str_extract_all(x, mypattern)[[1]], collapse=' '))
}
map_df(shopping_list, remove_short_words, 4)
# val
# <chr>
#1 apples
#2 flour
#3 sugar
#4 milk
Moreover, since str_extract_all
is vectorised you can also write this as -
remove_short_words <- function(x, n){
mypattern <- paste0("\\w{", n, ",}")
sapply(str_extract_all(x, mypattern), paste, collapse=' ')
}
tibble(val = remove_short_words(shopping_list, 4))
# val
# <chr>
#1 apples
#2 flour
#3 sugar
#4 milk
Upvotes: 1
Reputation: 2364
I do not fully understand what you are trying to do but if your shopping_list
is named this error goes away:
shopping_list2 <- shopping_list %>%
set_names(., shopping_list)
map2_df(shopping_list2, 4, function(x,y) remove_short_words(x,y))
Note that you don't need map2
and the additional anonymous function defintion if n
is constant. Also, use map_dfr
or map_dfc
(or map2_dfr
or map2_dfc
) to specify if the data should be merged rowwise or columnwise.
map_dfr(shopping_list2, remove_short_words, n = 4)
Upvotes: 1