Reputation: 1944
Is there a function or way unlist or unnest a vector within a dataframe using dplyr
? I have the following example.
library(tidyverse)
df <- tibble(x =
c("c(\"Police\", \"Pensions\")",
"c(\"potato\", \"sweetpotato\")"))
df
# A tibble: 2 x 1
x
<chr>
1 "c(\"Police\", \"Pensions\")"
2 "c(\"potato\", \"sweetpotato\")"
I'd like to get that dataframe column into a format like this.
> df
# A tibble: 4 x 1
x
<chr>
1 Police
2 Pensions
3 Potato
4 Sweetpotato
Upvotes: 3
Views: 1556
Reputation: 887098
One option is separate_rows
library(tidyverse)
df %>%
separate_rows(x) %>%
filter(!x %in% c('c', ''))
# A tibble: 4 x 1
# x
# <chr>
#1 Police
#2 Pensions
#3 potato
#4 sweetpotato
NOTE: It would be faster/efficient to separate and filter
Or another option is to extract the words between th quotes and then unnest
df %>%
mutate(x = str_extract_all(x, '(?<=")[A-Za-z]+')) %>%
unnest
# A tibble: 4 x 1
# x
# <chr>
#1 Police
#2 Pensions
#3 potato
#4 sweetpotato
On a slightly bigger data,
df1 <- df[rep(1:nrow(df), each = 1e5), ]
system.time({
df1 %>%
separate_rows(x) %>%
filter(!x %in% c('c', ''))
})
#. user system elapsed
# 0.916 0.033 0.939
system.time({
df1 %>%
mutate(x = str_extract_all(x, '(?<=")[A-Za-z]+')) %>%
unnest
})
# user system elapsed
# 0.763 0.015 0.773
system.time({
df1 %>%
mutate(x = map(x,~eval(parse(text=.)))) %>%
unnest
})
#user system elapsed
# 15.643 1.813 17.375
Upvotes: 4
Reputation: 47310
As you have R code stored in strings I think it's natural to use eval(parse(text= your_input))
.
Using unnest
on top of it you get :
df %>%
mutate(x = map(x,~eval(parse(text=.)))) %>%
unnest
# A tibble: 4 x 1
# x
# <chr>
# 1 Police
# 2 Pensions
# 3 potato
# 4 sweetpotato
Upvotes: 2