There are several solutions for this problem, here is a base R
solution:
Setup
df1 <- df2 <- df3 <- df4 <- mtcars[1:4, 1:3]
### store all relevant data.frames in a list
df_nms <- ls(pattern = "^df[0-9]$")
Base R
df1
# mpg cyl disp
# Mazda RX4 21.0 6 160
# Mazda RX4 Wag 21.0 6 160
# Datsun 710 22.8 4 108
# Hornet 4 Drive 21.4 6 258
for (nm in df_nms) {
tmp <- get(nm)
tmp[-1] <- lapply(tmp[-1], function(x) ave(x, FUN = function(x) x / x[1] * 100))
assign(nm, tmp)
}
df1
# mpg cyl disp
# Mazda RX4 21.0 100.00000 100.00
# Mazda RX4 Wag 21.0 100.00000 100.00
# Datsun 710 22.8 66.66667 67.50
# Hornet 4 Drive 21.4 100.00000 161.25
Howevr, using assign
is usually not a good design pattern, and I'd rather work with a list of data frames and change the list instead of the original values:
lapply(mget(df_nms),
function(df) {
df[-1] <- lapply(df[-1],
function(x) ave(x, FUN = function(x) x / x[1] * 100))
df})
# $df1
# mpg cyl disp
# Mazda RX4 21.0 100.00000 100.00
# Mazda RX4 Wag 21.0 100.00000 100.00
# Datsun 710 22.8 66.66667 67.50
# Hornet 4 Drive 21.4 100.00000 161.25
# $df2
# mpg cyl disp
# Mazda RX4 21.0 100.00000 100.00
# Mazda RX4 Wag 21.0 100.00000 100.00
# Datsun 710 22.8 66.66667 67.50
# Hornet 4 Drive 21.4 100.00000 161.25
# $df3
# mpg cyl disp
# Mazda RX4 21.0 100.00000 100.00
# Mazda RX4 Wag 21.0 100.00000 100.00
# Datsun 710 22.8 66.66667 67.50
# Hornet 4 Drive 21.4 100.00000 161.25
# $df4
# mpg cyl disp
# Mazda RX4 21.0 100.00000 100.00
# Mazda RX4 Wag 21.0 100.00000 100.00
# Datsun 710 22.8 66.66667 67.50
# Hornet 4 Drive 21.4 100.00000 161.25