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
