Matt
Matt

Reputation: 333

Multiply each other value in row with first value in row

I have the following data frame:

Date <- c("04.06.2013","05.06.2013","06.06.2013","07.06.2013","08.06.2013","09.06.2013")
 discharge <- c("1000","2000","1100","3000","1700","1600")
 concentration_1 <- c("25","20","11","6.4","17","16")
 concentration_2 <- c("1.4","1.7","2.7","3.2","4","4.7")
 concentration_3 <- c("1.2","1.3","1.9","2.2","2.4","3")
 concentration_4 <- c("1","0.92","2.5","3","3.4","4.8")

y <- data.frame(Date, discharge,concentration_1,concentration_2,concentration_3,concentration_4, stringsAsFactors=FALSE)
y$Date <- as.Date(y$Date, format ="%d.%m.%Y")
y[-1] <- sapply(y[-1], as.numeric)

In each row, I need to multiply each concentration with the discharge. I was looking into the apply function but couldn´t figure out how to solve it.

Upvotes: 0

Views: 862

Answers (3)

Rui Barradas
Rui Barradas

Reputation: 76663

The multiplication is vectorized, just use the columns you want to multiply as operands.

y[, 2] * y[, -(1:2)]

Upvotes: 2

Gregor Thomas
Gregor Thomas

Reputation: 146164

No apply needed, just multiply. But first let's get your data in decent shape.

They way you define your data, because you use quotes around the numbers, all the columns that should be numeric are factors. We use lapply to convert them safely to numeric:

y <- data.frame(Date, discharge,concentration_1,concentration_2,concentration_3,concentration_4)
y$Date <- as.Date(y$Date, format ="%d.%m.%Y")
str(y)
# 'data.frame': 6 obs. of  6 variables:
#  $ Date           : Date, format: "2013-06-04" "2013-06-05" "2013-06-06" "2013-06-07" ...
#  $ discharge      : Factor w/ 6 levels "1000","1100",..: 1 5 2 6 4 3
#  $ concentration_1: Factor w/ 6 levels "11","16","17",..: 5 4 1 6 3 2
#  $ concentration_2: Factor w/ 6 levels "1.4","1.7","2.7",..: 1 2 3 4 5 6
#  $ concentration_3: Factor w/ 6 levels "1.2","1.3","1.9",..: 1 2 3 4 5 6
#  $ concentration_4: Factor w/ 6 levels "0.92","1","2.5",..: 2 1 3 4 5 6

# convert all columns but the first safely to numeric
y[, -1] = lapply(y[, -1], function(x) as.numeric(as.character(x)))
str(y)
# 'data.frame': 6 obs. of  6 variables:
#  $ Date           : Date, format: "2013-06-04" "2013-06-05" "2013-06-06" "2013-06-07" ...
#  $ discharge      : num  1000 2000 1100 3000 1700 1600
#  $ concentration_1: num  25 20 11 6.4 17 16
#  $ concentration_2: num  1.4 1.7 2.7 3.2 4 4.7
#  $ concentration_3: num  1.2 1.3 1.9 2.2 2.4 3
#  $ concentration_4: num  1 0.92 2.5 3 3.4 4.8

With that done, we can just multiply the concentration columns by the discharge column. R will "recycle" the discharge column to multiply each of the concentration columns appropriately.

concentration_columns = paste0("concentration_", 1:4)
y[, concentration_columns] = y[, concentration_columns] * y[, "discharge"]
y
#        Date discharge concentration_1 concentration_2 concentration_3 concentration_4
# 1 2013-06-04      1000           25000            1400            1200            1000
# 2 2013-06-05      2000           40000            3400            2600            1840
# 3 2013-06-06      1100           12100            2970            2090            2750
# 4 2013-06-07      3000           19200            9600            6600            9000
# 5 2013-06-08      1700           28900            6800            4080            5780
# 6 2013-06-09      1600           25600            7520            4800            7680

Upvotes: 5

dCuba
dCuba

Reputation: 46

Once your values as not character (not in ""), you can use apply like this:

   new <- data.frame(y[,1:2],apply(y[,3:6],2,function(x) x*y$discharge))

Upvotes: 0

Related Questions