Yury Moskaltsov
Yury Moskaltsov

Reputation: 57

Dividing data frame by column vector

I have a data frame and I have a column from another data frame. I would like to divide every column of the first data frame by the column from another data frame. I can't seem to find a good answer without turning to matrices or doing a lot of work.

Type1 <- c(12,1,0,0,0,0,0,0)
Type2 <- c(29,4,0,1,0,1,0,0)
Type3 <- c(49,6,1,0,1,1,0,0)

Count <- c(897,525,220,150,183,106,129,89)
Count

df1 <- data.frame(Type1, Type2, Type3)

df2 <- data.frame(Count)


df1/df2$Count

Gives me enter image description here

I want all Type1 values divided by 897 and Type2 values divided by 525, and so on

Answer above gives incorrect values.

In Numpy it's so easy but can't find a solution in R.

Upvotes: 0

Views: 824

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 269634

There is some conflicting information in the question and comments so to be clear we assume you want to divide each column of df1 by Count so the three columns of the result should equal Type1 / Count, Type2 / Count and Type3 / Count respectively where Type1, Type2, Type3 and Count are defined in the question. We also assume that the calculation should be in terms of df1 and df2.

We can use /, sweep, Map, apply or mutate/across:

res1 <- df1 / df2$Count

res2 <- sweep(df1, 1, df2$Count, `/`)

res3 <- as.data.frame(Map(`/`, df1, df2))

res4 <- as.data.frame(apply(df1, 2, `/`, df2$Count))

library(dplyr)
res5 <- df1 %>% mutate(across(, `/`, df2$Count))


# check
res0 <- data.frame(Type1 = Type1 / Count, Type2 = Type2 / Count, Type3 = Type3 / Count)

identical(res1, res0)
## [1] TRUE

identical(res2, res0)
## [1] TRUE

identical(res3, res0)
## [1] TRUE

identical(res4, res0)
## [1] TRUE

identical(res5, res0)
## [1] TRUE

Upvotes: 0

akrun
akrun

Reputation: 887118

Based on the updated data, it seems to be dividing each corresponding value of 'df2' 'Count' with the corresponding column of 'df1'. So, we just replicate the 'Count'

> df2$Count[col(df1)]
 [1] 897 897 897 897 897 897 897 897 525 525 525 525 525 525 525 525 220 220 220 220 220 220 220 220

to make the lengths same and then divide by 'df1'

df1/df2$Count[col(df1)]
     Type1       Type2       Type3
1 0.013377926 0.055238095 0.222727273
2 0.001114827 0.007619048 0.027272727
3 0.000000000 0.000000000 0.004545455
4 0.000000000 0.001904762 0.000000000
5 0.000000000 0.000000000 0.004545455
6 0.000000000 0.001904762 0.004545455
7 0.000000000 0.000000000 0.000000000
8 0.000000000 0.000000000 0.000000000

Or take the transpose and divide

t(t(df1)/df2$Count)

Upvotes: 1

Related Questions