'Replace values conditionally, better way
I have a large dataframe with city names and many are misspelled. Right now I have corrected then manually, one by one, using the following code:
geo <- geo %>%
mutate(address = ifelse(hqcity == 'SMOERUM', 'Smørum, Denmark', address),
address = ifelse(hqcity == 'Staefa', 'Stäfa, Switzerland', address),
address = ifelse(hqcity == 'KOEBENHAVN' , 'København, Denmark', address),
address = ifelse(hqcity == 'Hoersholm' , 'Hørsholm, Denmark', address),
address = ifelse(hqcity == 'Buedelsdorf' , 'Büdelsdorf, Germany', address),
address = ifelse(hqcity == 'PFAEFFIKON' , 'Pfäffikon, Switzerland', address),
address = ifelse(hqcity == 'Ruemlang', 'Rümlang, Switzerland', address),
address = ifelse(hqcity == 'KILKENNY', 'Kilkenny, Ireland', address),
address = ifelse(hqcity == 'Kingscourt', 'Kingscourt, Ireland', address),
address = ifelse(hqcity == 'Soeborg', 'Søborg, Denmark', address),
address = ifelse(hqcity == 'Unterpremstaetten' , 'Unterpremstätten, Austria', address),
address = ifelse(hqcity == 'KOEBENHAVN S', 'København S, Denmark', address),
address = ifelse(hqcity == 'Maennedorf', 'Männedorf, Switzerland', address),
address = ifelse(hqcity == 'Santry' , 'Santry, Ireland', address),
address = ifelse(hqcity == 'Tralee', 'Tralee, Ireland', address),
address = ifelse(hqcity == 'KOEBENHAVN K', 'København K, Denmark', address),
address = ifelse(hqcity == 'Goeteborg', 'Göteborg, Sweden', address),
address = ifelse(hqcity == 'Goeppingen', 'Göppingen, Germany', address)
)
I want to know if somebody knows (or can imagine) a better way (with less repetitions, shorter, etc.) to make the same replacements. Thanks.
Solution 1:[1]
An alternative might be using a lookup vector. Starting with a data.frame like this
library(tibble)
df <- tibble::tribble(~a, ~b,
'SMOERUM', 'Smørum, Denmark',
'Staefa', 'Stäfa, Switzerland',
'KOEBENHAVN' , 'København, Denmark',
'Hoersholm' , 'Hørsholm, Denmark',
'Buedelsdorf' , 'Büdelsdorf, Germany',
'PFAEFFIKON' , 'Pfäffikon, Switzerland',
'Ruemlang', 'Rümlang, Switzerland',
'KILKENNY', 'Kilkenny, Ireland',
'Kingscourt', 'Kingscourt, Ireland',
'Soeborg', 'Søborg, Denmark',
'Unterpremstaetten' , 'Unterpremstätten, Austria',
'KOEBENHAVN S', 'København S, Denmark',
'Maennedorf', 'Männedorf, Switzerland',
'Santry' , 'Santry, Ireland',
'Tralee', 'Tralee, Ireland',
'KOEBENHAVN K', 'København K, Denmark',
'Goeteborg', 'Göteborg, Sweden' ,
'Goeppingen', 'Göppingen, Germany')
we create
lookup <- deframe(df)
Now use this vector inside mutate
:
library(dplyr)
geo %>%
mutate(adress = lookup[adress])
Solution 2:[2]
You can use dplyr's case_when like Martin said. Would be something like this:
geo <- geo %>%
mutate(adress = case_when(
hqcity == 'SMOERUM' ~ 'Smørum, Denmark',
hqcity == 'Staefa' ~ 'Stäfa, Switzerland',
#[...]
#[...]
#[...]
TRUE ~ adress
))
I guess its better in terms of processing time but still you need to specific the conditions manually. Unless theres some rule/pattern regulating the changes.
Solution 3:[3]
A possible solution (my geo
dataframe has 3 wrong cases and 1 correct):
library(tidyverse)
df <- data.frame(
wrong = c("SMOERUM","Staefa",
"KOEBENHAVN","Hoersholm","Buedelsdorf",
"PFAEFFIKON","Ruemlang","KILKENNY","Kingscourt",
"Soeborg","Unterpremstaetten","KOEBENHAVN S",
"Maennedorf","Santry","Tralee","KOEBENHAVN K",
"Goeteborg","Goeppingen"),
correct = c("Smørum, Denmark",
"Stäfa, Switzerland","København, Denmark",
"Hørsholm, Denmark","Büdelsdorf, Germany",
"Pfäffikon, Switzerland","Rümlang, Switzerland",
"Kilkenny, Ireland","Kingscourt, Ireland",
"Søborg, Denmark","Unterpremstätten, Austria",
"København S, Denmark","Männedorf, Switzerland",
"Santry, Ireland","Tralee, Ireland","København K, Denmark",
"Göteborg, Sweden","Göppingen, Germany")
)
geo <- data.frame(address = c("Hoersholm", "KILKENNY",
"KOEBENHAVN K", "Göppingen, Germany"))
geo %>%
rowwise %>%
mutate(address = ifelse(address %in% df$wrong,
filter(df %>% rowwise, address %in% wrong) %>%
select(correct) %>% deframe, address)) %>%
ungroup
#> # A tibble: 4 × 1
#> address
#> <chr>
#> 1 Hørsholm, Denmark
#> 2 Kilkenny, Ireland
#> 3 København K, Denmark
#> 4 Göppingen, Germany
Another possible solution, based on purrr::map_chr
:
library(tidyverse)
geo %>%
mutate(address = map_chr(address, ~ if (.x %in% df$wrong)
{filter(df, .x == wrong) %>% select(correct) %>% deframe} else {.x}))
#> address
#> 1 Hørsholm, Denmark
#> 2 Kilkenny, Ireland
#> 3 København K, Denmark
#> 4 Göppingen, Germany
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Martin Gal |
Solution 2 | Lucca Nielsen |
Solution 3 |