Reputation: 103
I have two dataframes in R that look as follows:
# A B C D
# 4 12 1 6
# 3 5 3 8
# 6 1 9 4
where A,B,C,D are column names, and
# id value
# A 10
# B 15
# C 12
# D 20
where id and value are column names
I'm trying to write a code to divide all values in each column by a "value" from second dataframe. I've tried searching here, using some packages and writing my own loops by hand and nothing works. My dataframes have thousands of columns so I can't type it out by hand. Please help and thank you.
Upvotes: 3
Views: 553
Reputation: 886998
Here is an option with deframe
library(tibble)
df1/deframe(df2)[col(df1)]
# A B C D
#1 0.4 0.80000000 0.08333333 0.3
#2 0.3 0.33333333 0.25000000 0.4
#3 0.6 0.06666667 0.75000000 0.2
Or using match
in base R
df1/df2$value[match(df2$id, names(df1))][col(df1)]
df1 <- structure(list(A = c(4L, 3L, 6L), B = c(12L, 5L, 1L), C = c(1L,
3L, 9L), D = c(6L, 8L, 4L)), class = "data.frame", row.names = c(NA,
-3L))
df2 <- structure(list(id = c("A", "B", "C", "D"), value = c(10L, 15L,
12L, 20L)), class = "data.frame", row.names = c(NA, -4L))
Upvotes: 1
Reputation: 26343
In baseR you could do
df1 / split(df2$value, names(df1))
# A B C D
#1 0.4 0.80000000 0.08333333 0.3
#2 0.3 0.33333333 0.25000000 0.4
#3 0.6 0.06666667 0.75000000 0.2
split(df2$value, names(df1))
returns a list that is sorted by names(df1)
:
split(df2$value, names(df1)
#$A
#[1] 10
#
#$B
#[1] 15
#
#$C
#[1] 12
#
#$D
#[1] 20
df1
is then divided columnwise by the values of that list.
data
df1 <- structure(list(A = c(4L, 3L, 6L), B = c(12L, 5L, 1L), C = c(1L,
3L, 9L), D = c(6L, 8L, 4L)), class = "data.frame", row.names = c(NA,
-3L))
df2 <- structure(list(id = c("A", "B", "C", "D"), value = c(10L, 15L,
12L, 20L)), class = "data.frame", row.names = c(NA, -4L))
Upvotes: 3
Reputation: 39858
One dplyr
solution could be:
df1 %>%
rowwise() %>%
mutate(across(everything())/df2$value)
A B C D
<dbl> <dbl> <dbl> <dbl>
1 0.4 0.8 0.0833 0.3
2 0.3 0.333 0.25 0.4
3 0.6 0.0667 0.75 0.2
Upvotes: 2