saladi - 2 months ago 6

R Question

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)]`

Answer

How about this:

```
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.