Darius
Darius

Reputation: 489

Multiplying all rows by another row from the same dataframe

DATA

I have a dataset similar to the dummy one below.

CODE

library(dplyr)
set.seed(111)
data <- tibble(ID = sort(sample(LETTERS, 10, F)),
                A = round(rnorm(10, 4, 1), 1),
                B = sample(0:20, 10, F),
                C = rep(c(33, 9), each = 5))
data <- rbind(data, c("ratio", 0.7, 0.25, 0.05))

QUESTION

I want to produce a new dataframe where each row is multiplied by the row called ratio (excluding first column with IDs). The ratio row can be then removed from the output table.

Is there a simple way of doing this in dplyr?

Upvotes: 0

Views: 456

Answers (1)

jdobres
jdobres

Reputation: 11957

dplyr is more suited to column-wise operations, less so row-wise operations like these. But it's fairly straightforward to do in base R:

library(dplyr)
set.seed(111)
data <- tibble(ID = sort(sample(LETTERS, 10, F)),
               A = round(rnorm(10, 4, 1), 1),
               B = sample(0:20, 10, F),
               C = rep(c(33, 9), each = 5))

ratio <- data.frame(A = 0.7, B = 0.25, C = 0.05) # your mutliplier
ratio <- ratio[rep(1, nrow(data)),] # replicated to match size of 'data'
data[2:4] <- data[2:4] * ratio # multiply

   ID        A     B     C
   <chr> <dbl> <dbl> <dbl>
 1 A      2.87  0.25  1.65
 2 B      1.75  2.5   1.65
 3 H      2.10  2     1.65
 4 I      2.17  4.5   1.65
 5 K      2.45  1.5   1.65
 6 L      2.66  2.75  0.45
 7 P      2.52  5     0.45
 8 S      4.06  4.75  0.45
 9 V      3.08  4.25  0.45
10 X      3.36  2.25  0.45

Alternately, you could avoid having to replicate your "ratio" data frame to match the size of the main data set by using Map:

ratio <- data.frame(A = 0.7, B = 0.25, C = 0.05)  
data[2:4] <- Map('*', data[2:4], ratio)

Upvotes: 2

Related Questions