Андрій zOFsky
Андрій zOFsky

Reputation: 133

How to add to each column of dataframe value from named vector?

I've got a dataframe df.

df <- data.frame(c(4,4,4,4,4,4), c(0,0,0,0,0,0))
colnames(df) <- c("a", "b")
> df
     a   b
1    4   0
2    4   0
3    4   0
4    4   0
5    4   0
6    4   0

And a named vector v, where names are corresponding to column names in my data frame.

v <- c(0.04, 0.01)
names(v) <- c("a", "b")
> v
      a       b 
   0.04    0.01 

There can be many columns in my dataframe and vector will always have corresponding names.

I want to add to each element of my column value from corresponding vector so I get result like this:

> df
     a      b
1    4.04   0.01
2    4.04   0.01
3    4.04   0.01
4    4.04   0.01
5    4.04   0.01
6    4.04   0.01

How can I do this with dplyr? All I've come up so far is

df %>% mutate_all(. = . + v[.])

But this gives me an error.

Error in mutate_all(., . = . + v[.]) : 
  argument 2 matches multiple formal arguments

The problem is I don't know how to point that corresponding column should be changed by corresponding vector.

Upvotes: 0

Views: 720

Answers (2)

akrun
akrun

Reputation: 887148

We can use base R (assuming the columns are in the same order)

df + v[col(df)]

Or using tidyverse

library(purrr)
map2_df(df, v[names(df)], `+`)

NOTE: the mutate_all loops through the columns of 'df', but it is not the case with 'v'. There is no index to select 'v' element that corresponds to the column in 'df' using mutate_all

Upvotes: 2

cardinal40
cardinal40

Reputation: 1263

This should work as a general case:

library(tidyverse)

df <-
  tibble(
    a = rep(4, 6),
    b = rep(0, 6)
  )

v <- c(0.04, 0.01)
names(v) <- c("a", "b")

v_df <- 
  v %>% 
  enframe() %>% 
  transmute(name, v_value = value)

df %>% 
  gather(key = name, value = value, a:b) %>% 
  left_join(v_df, by = "name") %>% 
  transmute(name, new_value = value + v_value)

Then you can re-spread out the data if you want it returned to the original format.

Upvotes: 0

Related Questions