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 unpack
ed
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
In R, Match Function for Rows or Columns of Matrix
Rank Per Row Over Multiple Columns in R
How to Store the Returned Value from a Shiny Module in Reactivevalues
String Split on Last Comma in R
Making a Zip Code Choropleth in R Using Ggplot2 and Ggmap
How Would You Fit a Gamma Distribution to a Data in R
R:Convert Nested List into a One Level List
How to Retrieve the Most Repeated Value in a Column Present in a Data Frame
Fast Way of Getting Index of Match in List
R: Bar Plot with Two Groups, of Which One Is Stacked
How to Count the Observations Falling in Each Node of a Tree
A^K for Matrix Multiplication in R
R - File.Choose() Customizing Dialogue Window
Transfer Values from One Dataframe to Another