I am looking to replace mutate_
with mutate
since there are deprecation warnings now and am unsure how to use some of the answers I have sought out on Stack Overflow. This answer has the deprecated quosure
issue and not sure how this one can be applied.
library(tibble)
library(dplyr)
library(magrittr)
library(rlang)
# two data frames/tibbles
df1 <-
data.frame(
w = c(0,9,8),
x = c(1,2,3),
y = c(4,5,6)
) %>% tibble()
df2 <-
data.frame(
x = c(9,9,9),
y = c(1,1,1),
z = c(6,6,6)
) %>% tibble()
# the original function
swapThem <- function(to, from) {
cols <- colnames(from)
if (length(cols) != 0) {
# Loop through `from` columns and if there's a match in `to`, copy and paste
# it into `to`
for (i in seq_along(cols)) {
col <- cols[i]
if (col %in% colnames(to)) {
print(col)
dots <-
stats::setNames(list(lazyeval::interp(
~ magrittr::use_series(from, x), x = as.name(col)
)), col)
to <- to %>%
#dplyr::mutate(.dots = dots)
dplyr::mutate_(.dots = dots)
} else {
next
}
}
}
return(to)
}
CodePudding user response:
Here is a simpler base R alternative -
swapThem <- function(to, from) {
cols <- intersect(colnames(to), colnames(from))
if(length(cols)) to[cols] <- from[cols]
to
}
swapThem(df1, df2)
# A tibble: 3 × 3
# w x y
# <dbl> <dbl> <dbl>
#1 0 9 1
#2 9 9 1
#3 8 9 1
The output is similar when I run your code with swapThem(df1, df2)
I get
#[1] "x"
#[1] "y"
# A tibble: 3 × 3
# w x y
# <dbl> <dbl> <dbl>
#1 0 9 1
#2 9 9 1
#3 8 9 1
CodePudding user response:
There are easier ways to do this (see Ronak Shah's base R approach, for example), however since you specifically asked about how to switch from mutate_
to mutate
, you can adjust your original code in this way:
swapThem <- function(to, from) {
cols <- colnames(from)
if (length(cols) != 0) {
# Loop through `from` columns and if there's a match in `to`, copy and paste
# it into `to`
for (i in seq_along(cols)) {
col <- cols[i]
if (col %in% colnames(to)) {
to <- to %>% dplyr::mutate(!!sym(col) := from[[col]])
} else {
next
}
}
}
return(to)
}
Note that you can also use {{}}
, like this:
to <- to %>% dplyr::mutate({{col}} := from[[col]])
Here is another tidy approach, that uses bind_cols
. The relocate is to ensure that the order of columns in to
is preserved
swapThem <- function(to,from) {
bind_cols(
to %>% select(all_of(setdiff(colnames(to), colnames(from)))),
from %>% select(all_of(intersect(colnames(to), colnames(from))))
) %>%
relocate(colnames(to))
}