简体   繁体   中英

How to subtract one column from multiple columns in a dataframe in R using dplyr

I am using gapminder data to subtract values of 1 country gdpPercapita from rest of the countries.

I have referred to the link on same topic but still getting issues. Subtract a column in a dataframe from many columns in R )

Issue When I subtract a column (eg. India) from all other countries then in return I am getting India as 0 values (which is correct) but it didn't subtract India from other columns for example Vietnam.

Pivoting data for comparing India, Vietnam before Subtraction

  gapminder %>% 
    select(country, year, gdpPercap) %>% 
    pivot_wider(names_from = country, values_from = gdpPercap) %>% 
    arrange(year) %>% 
    select(year,India,Vietnam)  

year     India      Vietnam
<int>    <dbl>      <dbl>

1952    546.5657    605.0665        
1957    590.0620    676.2854        
1962    658.3472    772.0492        
1967    700.7706    637.1233        
1972    724.0325    699.5016        
1977    813.3373    713.5371        
1982    855.7235    707.2358    

Comparing India, Vietnam after Subtraction

  gapminder %>% 
    select(country, year, gdpPercap) %>% 
    pivot_wider(names_from = country, values_from = gdpPercap) %>% 
    arrange(year) %>% 
    mutate_at(vars(-matches("year")), ~ . - India) %>% 
    select(year,India,Vietnam)

year     India      Vietnam
<int>    <dbl>      <dbl>

1952    0         605.0665      
1957    0         676.2854      
1962    0         772.0492      
1967    0         637.1233      
1972    0         699.5016      
1977    0         713.5371      
1982    0         707.2358  

I am not sure what is wrong with the code ?

Appreciate any help !!

It is a behavior of mutate_at , you could switch to across (as suggested by @RonakShah) and do:

gapminder %>% 
  select(country, year, gdpPercap) %>% 
  pivot_wider(names_from = country, values_from = gdpPercap) %>% 
  arrange(year) %>% 
  mutate(across(-matches('year'), ~  . - India)) %>%
  select(year, India, Vietnam)

With mutate_at , you would need to make sure that the column used for calculation is the last one in your data - you could use relocate to move it, like below:

gapminder %>% 
  select(country, year, gdpPercap) %>% 
  pivot_wider(names_from = country, values_from = gdpPercap) %>% 
  arrange(year) %>% 
  relocate(India, .after = last_col()) %>%
  mutate_at(vars(-matches('year')), ~ . - India) %>%
  select(year, India, Vietnam)

Output:

# A tibble: 12 x 3
    year India Vietnam
   <int> <dbl>   <dbl>
 1  1952     0    58.5
 2  1957     0    86.2
 3  1962     0   114. 
 4  1967     0   -63.6
 5  1972     0   -24.5
 6  1977     0   -99.8
 7  1982     0  -148. 
 8  1987     0  -156. 
 9  1992     0  -175. 
10  1997     0   -72.9
11  2002     0    17.7
12  2007     0   -10.6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM