Reputation: 5
I am trying to add a new column into a data frame by matching words from a different column. To use mtcars as an example, I want to create a column "country" by scanning each rowname for a string. To go through the first few rows in pseudocode:
if "Mazda" in rowname then "Japan"
if "Datsun" in rowname then "Japan"
if "Hornet" in rowname then "USA"
etc
I've tried using mutate with the map function, but to no avail. Any help would be appreciated.
Upvotes: 0
Views: 105
Reputation: 32548
Use a named vector (x
in this example)
library(dplyr)
x = c(Mazda = "Japan", Datsun = "Japan", Hornet = "USA")
mtcars %>%
mutate(Make = row.names(.)) %>%
select(Make) %>%
mutate(Country = x[sapply(strsplit(Make, " "), function(x) x[1])])
Upvotes: 0
Reputation: 757
You want to use case_when()
or ifelse()
:
library(dplyr)
mt <- head(mtcars, 5)
mt %>%
mutate(new_col = case_when(
mpg == 21.0 ~ "new",
TRUE ~ "A"
))
mpg cyl disp hp drat wt qsec vs am gear carb new_col
1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 new
2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 new
3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 A
4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 A
5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 A
Upvotes: 1
Reputation: 887153
Instead of using multiple if/else
or nested ifelse
, we can have a key/val dataset and join with the original data
library(tibble)
library(dplyr
library(stringr)
keyvaldat <- tibble(make = c("Mazda", "Datsun", "Hornet"),
Country = c("Japan", "Japan", "USA"))
rownames_to_column(mtcars, "rn") %>%
mutate(make = word(rn, 1)) %>%
left_join(keyvaldat) %>%
head(4)
# rn mpg cyl disp hp drat wt qsec vs am gear carb make Country
#1 Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 Mazda Japan
#2 Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 Mazda Japan
#3 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 Datsun Japan
#4 Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 Hornet USA
NOTE: If there are 100- values to change, then it would be 100 ifelse
statements. Better would be a join
Upvotes: 0