Multiply Columns in a Data Frame by a Vector

Multiply columns in a data frame by a vector

Transposing the dataframe works.

c1 <- c(1,2,3)
c2 <- c(4,5,6)
c3 <- c(7,8,9)
d1 <- data.frame(c1,c2,c3)
v1 <- c(1,2,3)
t(t(d1)*v1)
# c1 c2 c3
#[1,] 1 8 21
#[2,] 2 10 24
#[3,] 3 12 27

EDIT: If all columns are not numeric, you can do the following

c1 <- c(1,2,3)
c2 <- c(4,5,6)
c3 <- c(7,8,9)
d1 <- data.frame(c1,c2,c3)

# Adding a column of characters for demonstration
d1$c4 <- c("rr", "t", "s")

v1 <- c(1,2,3)

#Choosing only numeric columns
index <- which(sapply(d1, is.numeric) == TRUE)
d1_mat <- as.matrix(d1[,index])

d1[,index] <- t(t(d1_mat)*v1)
d1
# c1 c2 c3 c4
#1 1 8 21 rr
#2 2 10 24 t
#3 3 12 27 s

tidyverse solution for multiplying columns by a vector

If it is by row, then one option is c_across

library(dplyr)
library(stringr)
library(tibble)
new <- as_tibble(setNames(as.list(v1), names(d1)))
d1 %>%
rowwise %>%
mutate(c_across(everything()) * new) %>%
rename_with(~ str_c("pro_", .x), everything()) %>%
bind_cols(d1, .)

-output

   1 c2 c3 pro_c1 pro_c2 pro_c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27

Or another option is map2

library(purrr)
map2_dfc(d1, v1, `*`) %>%
rename_with(~ str_c("pro_", .x), everything()) %>%
bind_cols(d1, .)

-output

 c1 c2 c3 pro_c1 pro_c2 pro_c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27

Also, with the OP' approach, it is a data.frame column. It can be unpacked

library(tidyr)
d1 |>
mutate(pro = sweep(cur_data(), 2, v1, `*`)) |>
unpack(pro, names_sep = "_")

-output

# A tibble: 3 × 6
c1 c2 c3 pro_c1 pro_c2 pro_c3
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27

EDIT: Based on @deschen comments with names_sep

What is the right way to multiply data frame by vector?

This works too:

data.frame(mapply(`*`,df,v))

In that solution, you are taking advantage of the fact that data.frame is a type of list, so you can iterate over both the elements of df and v at the same time with mapply.

Unfortunately, you are limited in what you can output from mapply: as simple list, or a matrix. If your data are huge, this would likely be more efficient:

data.frame(mapply(`*`,df,v,SIMPLIFY=FALSE))

Because it would convert it to a list, which is more efficient to convert to a data.frame.

Multiply each column of a data frame by the corresponding value of a vector

Here is another option using sweep

sweep(dframe, 2, vector, "*")
# V1 V2 V3
#1 2 12 28
#2 4 15 32
#3 6 18 36

Or using col

dframe*vector[col(dframe)]

Multiply columns of a data.table by a vector

Map was designed for this:

dt[, Map("*", .SD, v)]
# col1 col2 col3
#1: 1 4 9
#2: 1 4 9
#3: 1 4 9
#4: 1 4 9

Also works with a data.frame:

DF <- as.data.frame(dt)
as.data.frame(Map("*", DF, v))
# col1 col2 col3
#1 1 4 9
#2 1 4 9
#3 1 4 9
#4 1 4 9

Multiply columns using values in a list

You could do:

df * coef[col(df)]

or eve

data.frame(t(t(df) * coef))

Multiply a column in a list element by a vector using map() in R to create new columns

Here's one strategy. Basically you use map_dfc to turn the vector into a bunch of columns.

map(my_list, function(x) {
bind_cols(x, map_dfc(set_names(vector, paste0("Column_", vector)), ~x$Column2*.x))
})

Since we have a nested map, I used an explicit function for the outer function that receives each data.frame. This will help differentiation between x (the data.frame) and .x (the value of vector). We use set_names so that map_dfc will use those as the names of the new columns it creates. The actual multiplication doesn't need a map because multiplication is vectorized in R.

Is there an R function to multiply two columns contain vectors in a data frame together?

column bind both dataframes

df = cbind(dataframe1, dataframe2)

Change both columns to numeric

raw$Prices = as.numeric(unlist(raw$Prices))
raw$Quantities = as.numeric(unlist(raw$Quantities))
Order$Delivery_Fee = as.numeric(unlist(Order$Delivery_Fee))

Multiply columns with dplyr

library(dplyr)
df <- df %>% mutate(order = Prices * Quantities)

final result

df$final_price <- df$order + df$Delivery_Fee

Multiply values across each column by weight in another data.frame in R

You can use sweep and match -

df[-1] <- sweep(df[-1],2, weights$V1[match(names(df[-1]),rownames(weights))],`*`)

df
# id a b d EE f
#1 this 0.7494769 -0.1743717 5.293633 NA 4.175490
#2 is 0.9081165 2.7259681 9.884781 NA -8.807325
#3 an -0.1399082 0.5559418 -4.374990 NA -3.922983
#4 example -0.5804764 0.7803247 -10.545803 NA 3.467420
#5 data.frame 0.7755359 -1.1257980 -10.848448 NA 3.161471
#6 for -2.3269836 1.2253498 12.256612 NA 5.404699
#7 stackoverflow 0.8065261 -1.3295363 -3.270386 NA -5.228465
#8 please -0.3535157 -0.4973664 4.212379 NA 2.099392
#9 help -0.3637245 1.6810690 4.156319 NA 2.157794
#10 me -1.1767322 0.4480855 -1.102092 NA -4.835156

Multiplying all columns in dataframe by single column

Also try

df1 * t(C)
# F1 F2 F3
#1 2.0 2.0 2.0
#2 5.0 5.0 5.0
#3 16.0 16.0 16.0
#4 4.5 4.5 4.5

When we try to multiply data frames they must be of the same size.

df1 * C

error in Ops.data.frame(df1, C) :
‘*’ only defined for equally-sized data frames

t() turns C into a matrix, i.e. a vector with dimension attribute of length 4. This vector gets recycled when we multiply it with df1.

What would also work in the same way (and might be faster than transposing C):

df1 * C$C

or

df1 * unlist(C)


Related Topics



Leave a reply



Submit