在 R 中对列出的数据帧使用扫描(或类似的东西)

using sweep (or something similar) in R for listed data frames

我正在为几个 dfs 做一些转换步骤,所以我冒险进入了应用、lapply、扫描等的美丽世界。不幸的是,我在尝试对列出的 dfs 使用扫描时遇到了困难.

我想做的是根据每个数据框第一行的平均值计算每个值的百分比。

所以我将我的 dfs 放入一个列表中,最终看起来像这样;

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

现在我计算每一行的平均值并存储它

  one.hundred <- lapply(list.one, function(i) 
    {rowMeans(i[1,], na.rm=T)})

> one.hundred
[[1]]
       1 
17.93325 

[[2]]
       1 
4.432355

现在我计算它们的百分比(与第二个列表中存储的值相比),我想出的最好办法是这个相当乏味的解决方法:

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)

如果有人可以向我推荐更简单的解决方案,最好是基于列表的解决方案,那将很有帮助。

非常感谢。

这是 sapplyMap 的另一种方法,它也将 return 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")))