Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiply each cell of a data.frame with it's weight

Tags:

dataframe

r

apply

What I want to do is embarrassing simple - nevertheless I fail.

I have a data.frame with "characters" and "numerics". One of the columns of the data.frame represents the weights.

I want to multiply every cell of the data frame with the corresponding weight (if it's a numeric).

How do I do that (best without using a nested loop).

Thank you in advance!

Example:

   c1   c2   w   
l1 abc  2    1
l2 dxf  3    0.5
l3 ghi  4    1.5

should become

   c1   c2   w   
l1 abc  2    1
l2 dxf  1.5  0.5
l3 ghi  6    1.5
like image 253
speendo Avatar asked Feb 23 '11 13:02

speendo


People also ask

How do you multiply in a data frame?

The mul() method multiplies each value in the DataFrame with a specified value. The specified value must be an object that can be multiplied with the values of the DataFrame.

How do you multiply all values in a DataFrame column?

Use the * operator to multiply a column by a constant number Select a column of DataFrame df using syntax df["column_name"] and set it equal to n * df["column_name"] where n is the number to multiply by.

How do pandas Series multiply?

The mul() method of the pandas Series multiplies the elements of one pandas Series with another pandas Series returning a new Series. Multiplying of two pandas. Series objects can be done through applying the multiplication operator “*” as well.

How do I multiply multiple columns in pandas?

DataFrame. multiply() Method. This method is used to multiply two dataframe columns, we need to define the column which has to be multiplied inside square brackets with our dataframe like df[col], and then multiply() method will take another column with whom we want to multiply.


2 Answers

For a reproducible example, dd is a data frame with a mixture of variable types, with W being the weights.

dd <- data.frame(G=gl(2,2), X=rnorm(4), Y=1L:4L, Z=letters[1:4], W=0.3:3.3)
num.vars <- names(dd)[sapply(dd, is.numeric)]  #select numeric variables
num.vars <- setdiff(num.vars, "W")  # remove the weight variable
dd[num.vars] <- dd[num.vars] * dd$W  # multiply
like image 115
Aniko Avatar answered Oct 12 '22 00:10

Aniko


Vectorise!

> dat <- data.frame(c1 = c("abc","dxf","ghi"), c2 = 2:4, w = c(1,0.5,1.5))

Effectively, you want c2 * w, but we need to tell R to look inside the data frame:

> with(dat, c2 * w)
[1] 2.0 1.5 6.0

Which we can insert back into dat in a single line:

> dat <- within(dat, c3 <- c2 * w)
> dat
   c1 c2   w  c3
1 abc  2 1.0 2.0
2 dxf  3 0.5 1.5
3 ghi  4 1.5 6.0

(Replace c3 with c2 if you want to overwrite the existing c2.)

If you have more than one numeric column other than weights, a slighlty different strategy is required if you want to automate it (i.e. not tell R which columns to multiply by w).

> ## dummy data
> dat2 <- data.frame(c1 = c("abc","dxf","ghi"), c2 = 2:4, w = c(1,0.5,1.5),
                     c3 = 5:7, c4 = 3:5)
> ## select the columns we want, all numerics, but not `w`
> want <- sapply(dat2, is.numeric) & names(dat2) != "w"
> ## then use want to index into dat2
> dat2[, want] <- with(dat2, dat2[, want] * w)
> dat2
   c1  c2   w   c3  c4
1 abc 2.0 1.0  5.0 3.0
2 dxf 1.5 0.5  3.0 2.0
3 ghi 6.0 1.5 10.5 7.5
like image 36
Gavin Simpson Avatar answered Oct 12 '22 00:10

Gavin Simpson