saladi - 1 year ago 77
R Question

# What is the right way to multiply a named vector by a dataframe?

Similar to this SO question, what is the right way to multiply a named vector by a dataframe, such that each row is multiplied by corresponding element of the vector?

``````df <- data.frame(A=1:5, B=2:6)
v <- c(2, 0)
names(v) <- c("B", "A")
``````

I would like the following output:

``````   A  B
1  0  4
2  0  6
3  0  8
4  0 10
5  0 12
``````

None of the suggested solutions from the other question match column names with the names of the vector. For example,

``````dt <- data.table(df)
for (i in seq_along(dt))
dt[, i := dt[[i]] * v[i], with = F]

dt
A B
1:  2 0
2:  4 0
3:  6 0
4:  8 0
5: 10 0
``````

I can do it by reordering v, but I wonder whether there's a better way to do this:

``````v <- v[colnames(df)]
``````

``````r <- mapply('*', df, v[names(df)])
# or equivalently: mapply(function(x,y) x*y, df, v[names(df)])

#     A  B
#[1,] 0  4
#[2,] 0  6
#[3,] 0  8
#[4,] 0 10
#[5,] 0 12
``````

`v[names(df)]` will give the vector elements in the same order as they are in `df`, so column-name-respective, so to say.

If you want to have `r` as data frame, just do `as.data.frame(r)`.

This is from `?mapply`

mapply is a multivariate version of sapply. mapply applies FUN to the first elements of each ... argument, the second elements, the third elements, and so on. Arguments are recycled if necessary.

`FUN` is `*` in our setting.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download