Reputation: 309
I'm doing a handful of transformation steps for several dfs, so I have ventured into the beautiful world of apply, lapply, sweep, etc. Unfortunately I got stuck trying to use sweep for listed dfs.
What I would like to do, is calculate the percentage of each value, based on the mean of each data frame's first row.
So I put my dfs into a list which ends up looking something like this;
df1 <- read.table(header = TRUE, text = "a b
1 16.26418 19.60232
2 16.09745 18.44320
3 17.25242 18.21141
4 17.61503 17.64766
5 18.35453 19.52620")
df2 <- read.table(header = TRUE, text = "a b
1 4.518654 4.346056
2 4.231176 4.175854
3 2.658694 4.999478
4 3.348019 2.345594
5 3.103378 2.556690")
list.one <- list(df1,df2)
> list.one
[[1]]
a b
1 16.26418 19.60232
2 16.09745 18.44320
3 17.25242 18.21141
4 17.61503 17.64766
5 18.35453 19.52620
[[2]]
a b
1 4.518654 4.346056
2 4.231176 4.175854
3 2.658694 4.999478
4 3.348019 2.345594
5 3.103378 2.556690
Now I calculate the mean of each first row and store it
one.hundred <- lapply(list.one, function(i)
{rowMeans(i[1,], na.rm=T)})
> one.hundred
[[1]]
1
17.93325
[[2]]
1
4.432355
Now I calculate their percentage (as compared to the values stored in the second list) and the best I came up with is this rather tedious workaround:
df1.per<-sweep(list.one[[1]], 1, one.hundred[[1]],
function(x,y){100/y*x})
df2.per<-sweep(list.one[[2]], 1, one.hundred[[2]],
function(x,y){100/y*x})
list.new(df1.per,df2.per)
If somebody could suggest me simpler, preferably list based solution that would be great help.
Thanks a lot.
Upvotes: 0
Views: 325
Reputation: 70316
Here's another approach with sapply
and Map
that will also return a list of data.frames:
means <- sapply(list.one, function(df) rowMeans(df[1, ], na.rm = TRUE))
Map(function(vec, df) df/vec*100, means, list.one)
#$`1`
# a b
#1 90.69287 109.30713
#2 89.76315 102.84360
#3 96.20353 101.55109
#4 98.22553 98.40748
#5 102.34916 108.88266
#
#$`1`
# a b
#1 101.94702 98.05298
#2 95.46113 94.21299
#3 59.98378 112.79507
#4 75.53589 52.91981
#5 70.01646 57.68243
> dput(list.one)
list(structure(list(a = c(16.26418, 16.09745, 17.25242, 17.61503,
18.35453), b = c(19.60232, 18.4432, 18.21141, 17.64766, 19.5262
)), .Names = c("a", "b"), class = "data.frame", row.names = c("1",
"2", "3", "4", "5")), structure(list(a = c(4.518654, 4.231176,
2.658694, 3.348019, 3.103378), b = c(4.346056, 4.175854, 4.999478,
2.345594, 2.55669)), .Names = c("a", "b"), class = "data.frame", row.names = c("1",
"2", "3", "4", "5")))
Upvotes: 1