0
votes

I have a dataset which includes (among others many variables) 5 columns indicating the country where the data is from, coded as a number. I would like to create a new variable indicating the country in plain text (e.g. Spain instead of 312).

Here is a sample of the data with only 5 rows and 2 columns for reproducibility:

c <- structure(list(CountryAP = structure(c(109, NA, 124, NA, NA), label = "Country of the Child Helpline (Asia Pacific region)", labels = c(Afghanistan = 109,  `New Zealand` = 124), class = "haven_labelled"), 
           CountryEr = structure(c(NA, 313, NA, 287, 278), label = "Country of the Child Helpline (Europe region)", labels = c( Azerbaijan = 278, Finland = 287, Sweden = 313), class = "haven_labelled")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L))

I want to compute a new variable (called Country) with all the countries pulled from the numbers from the variables called CountryAP and CountryEr.

I tried this:

c <- c %>%   mutate(Country = ifelse(CountryAP == 109, 'Afghanistan', ifelse(CountryAP == 124, 'New Zealand', ifelse(CountryEr == 313, 'Sweden', ifelse(CountryEr == 287, 'Finland', ifelse(CountryEr == 278, 'Azerbaijan','N/A'))))))

But although it correctly computes the rows which include values in the first variable (CountryAP), it ignores the information about the second variable (CountryEr) and gives me only this:

   CountryAP    CountryEr     Country
1  109          NA            Afghanistan
2  NA           313           NA
3  124          NA            New Zealand
4  NA           287           NA
5  NA           278           NA

When I run only the CountryEr part it runs correctly.

Any idea how to make the ifelse statement accept to look at a different variable?

Any help would be much appreciated!

2
I cannot recreate c. You didn't copy all the output. - DJV
In addition, try to look into case_when, instead of using nested ifelse. - DJV
Thanks for pointing this out and sorry about that. I've edited my post to correct for c. - Andrea

2 Answers

1
votes

Thank you, case_when indeed solved my problem:

c <- c %>%   mutate(Country = case_when(CountryAP == 109 ~ 'Afghanistan',
                         CountryAP == 124 ~  'New Zealand',
                         CountryEr == 313 ~ 'Sweden',
                         CountryEr == 287  ~ 'Finland',
                         CountryEr == 278 ~ 'Azerbaijan'))
1
votes

I can think of two ways to do this. First, you'll want to get your country codes unified into a single column:

c <- c %>% 
  mutate(CountryCode = ifelse(is.na(CountryAP), CountryEr, CountryAP))

  CountryAP CountryEr CountryCode
      <dbl>     <dbl>       <dbl>
1       109        NA         109
2        NA       313         313
3       124        NA         124
4        NA       287         287
5        NA       278         278

Using dplyr::case_when

This function allows us to specify multiple conditions without confusing nested structures:

c <- c %>% 
  mutate(CountryName = case_when(
    CountryCode == 109 ~ 'Afghanistan',
    CountryCode == 124 ~ 'New Zealand',
    CountryCode == 313 ~ 'Sweden',
    CountryCode == 287 ~ 'Finland',
    CountryCode == 278 ~ 'Azerbaijan'
  ))

  CountryAP CountryEr CountryCode CountryName
      <dbl>     <dbl>       <dbl> <chr>      
1       109        NA         109 Afghanistan
2        NA       313         313 Sweden     
3       124        NA         124 New Zealand
4        NA       287         287 Finland    
5        NA       278         278 Azerbaijan 

Merging a secondary table

Alternately, you could store your country code and country name values in a separate table, and merge them into your primary data:

df.countries <- data.frame(
  CountryCode = c(109, 124, 313, 287, 278),
  CountryName = c('Afghanistan', 'New Zealand', 'Sweden', 'Finland', 'Azerbaijan')
)

  CountryCode CountryName
1         109 Afghanistan
2         124 New Zealand
3         313      Sweden
4         287     Finland
5         278  Azerbaijan

c <- c %>% 
  left_join(df.countries, by = 'CountryCode')

  CountryAP CountryEr CountryCode CountryName
      <dbl>     <dbl>       <dbl> <chr>      
1       109        NA         109 Afghanistan
2        NA       313         313 Sweden     
3       124        NA         124 New Zealand
4        NA       287         287 Finland    
5        NA       278         278 Azerbaijan