I have a data frame of values:
df <- structure(list(X1 = 1:2, X2 = c(1L, 3L), X3 = 2:3), class = "data.frame", row.names = c(NA, -2L))
X1 X2 X3
1 1 1 2
2 2 3 3
And a data frame containing replacement values:
replacement_values <- structure(list(num = c("1", "2", "3"), . = c("cat",
"dog", "mouse")), row.names = c(NA,
-3L), class = "data.frame")
num .
1 1 cat
2 2 dog
3 3 mouse
For example, every time the number "1" is found in the first data frame, I would like it replaced by the word "cat", every time "2" is found I want it replaced by "dog" and every time "3" is found I want it replaced by "mouse". So Ideally I would end up with a data frame that looks like this:
X1 X2 X3
1 cat cat dog
2 dog mouse mouse
I could do it like this but it's very long winded and doesn't use the replacement_values data frame:
df <- df %>%
dplyr::mutate(
X1 = X1 %>%
gsub("1", "cat", .) %>%
gsub("2", "dog", .) %>%
gsub("3", "mouse", .),
X2 = X2 %>%
gsub("1", "cat", .) %>%
gsub("2", "dog", .) %>%
gsub("3", "mouse", .),
X3 = X3 %>%
gsub("1", "cat", .) %>%
gsub("2", "dog", .) %>%
gsub("3", "mouse", .)
)
Is there a better way?
CodePudding user response:
You could first unlist
the values in your dataframe df
and match
the values from replacement_values
with df
like this:
df[] <- replacement_values$.[match(unlist(df), replacement_values$num)]
df
#> X1 X2 X3
#> 1 cat cat dog
#> 2 dog mouse mouse
Created on 2022-09-16 with reprex v2.0.2
CodePudding user response:
library(tidyverse)
replacement_values <-
structure(list(
num = c("1", "2", "3"),
. = c("cat",
"dog", "mouse")
),
row.names = c(NA,-3L),
class = "data.frame")
df <-
structure(list(
X1 = 1:2,
X2 = c(1L, 3L),
X3 = 2:3
),
class = "data.frame",
row.names = c(NA,-2L))
map_df(df, ~replacement_values$.[match(.x, table = replacement_values$num)])
#> # A tibble: 2 x 3
#> X1 X2 X3
#> <chr> <chr> <chr>
#> 1 cat cat dog
#> 2 dog mouse mouse
Created on 2022-09-16 with reprex v2.0.2
CodePudding user response:
With dplyr
, match
is still the best option. Use across
to apply the change over all functions. Note that it's preferable in this case to use function(x)
instead of the usual ~
since you have .
as a variable name.
df %>%
mutate(across(everything(), function(x) replacement_values$.[match(x, replacement_values$num)]))
output
X1 X2 X3
1 cat cat dog
2 dog mouse mouse
CodePudding user response:
Below is to demonstrate that lapply can be useful.
df <- structure(list(X1 = 1:2, X2 = c(1L, 3L), X3 = 2:3), class = "data.frame", row.names = c(NA, -2L))
df[]=lapply(df, function(x) gsub(1,"cat", x))
df[]=lapply(df, function(x) gsub(2,"dog", x))
df[]=lapply(df, function(x) gsub(3,"mouse", x))
the result:
X1 X2 X3
<chr> <chr> <chr>
cat cat dog
dog mouse mouse