Reputation: 1011
How do I paste together a dynamic subset of columns from a data.frame using dplyr?
If I have a following function:
d = data.frame(a = 1:5, b=2:6, c=3:7)
fun = function(d, colnames){
d$f = Reduce(function(x,y)paste(x,y,sep='_'), d[,colnames])
return(d)
}
fun(d, c('a','b'))
fun(d, c('b','c'))
fun(d, c('a','b','c'))
How do I rewrite the function using dplyr?
Upvotes: 1
Views: 952
Reputation: 3883
Updated answer, use tidyr::unite
!
It allows dynamic selection of columns, and has options for excluding missing values (NA
) and keeping or dropping input variables.
d = data.frame(a = 1:5, b=2:6, c=3:7)
d |>
tidyr::unite("new_col", a:c, remove = FALSE)
#> new_col a b c
#> 1 1_2_3 1 2 3
#> 2 2_3_4 2 3 4
#> 3 3_4_5 3 4 5
#> 4 4_5_6 4 5 6
#> 5 5_6_7 5 6 7
Created on 2023-05-23 with reprex v2.0.2
Upvotes: 0
Reputation: 13135
Here is a version of your function using dplyr
and rlang
library(dplyr)
library(rlang)
fun = function(d,a,b){
a.var <- enquo(a)
b.var <- enquo(b)
d %>% mutate(f = paste(!!a.var,!!b.var, sep="_"))
}
fun(d,a,b)
fun = function(d,...){
#browser()
vars <- quos(...)
d %>% mutate(f = paste(!!!vars, sep="_"))
}
fun(d,a)
fun(d,c,a)
fun(d,a,b,c)
Upvotes: 4
Reputation: 501
This works for your example:
> library(dplyr)
> d = data.frame(a = 1:5, b=2:6, c=3:7)
> d <- d %>% mutate(f = paste(a,b,sep='_'))
> d
a b c f
1 1 2 3 1_2
2 2 3 4 2_3
3 3 4 5 3_4
4 4 5 6 4_5
5 5 6 7 5_6
EDIT:
After your edit, this will work for you:
> library(dplyr)
> d = data.frame(a = 1:5, b=2:6, c=3:7)
> colnames <- c("a", "c")
> d <- d %>% mutate(f = paste(!!as.name(colnames[1]),!!as.name(colnames[2]),sep='_'))
> d
a b c f
1 1 2 3 1_3
2 2 3 4 2_4
3 3 4 5 3_5
4 4 5 6 4_6
5 5 6 7 5_7
Upvotes: 1