如何使用ddply计算数据框中每个单元格的百分比?

时间:2013-06-05 22:43:12

标签: r plyr

我的猜测是使用ddply很容易,但我仍然是R的新手,无法理解它。

我有一个看起来像这样的data.frame

txt <- "label var1 var2 var3 var4 var5 var6 var7
lab1 401 80 57 125 118 182 83
lab2 72 192 80 224 182 187 178
lab3 7 152 134 104 105 80 130
lab4 3 58 210 30 78 33 87
lab5 1 2 3 1 1 2 6"

mydata <- read.table(textConnection(txt), sep = " ", header = TRUE)

这样做我可以一次将一个变量转换为百分比

mydata$var1 <- round(prop.table(mydata$var1),3)*100

但是如何在一个笔划中的data.frame中使用所有变量(var1:var7)?

注意:它进入一个函数,其中变量的长度和数量不时不同,因此代码应该对此敏感。

提前谢谢

4 个答案:

答案 0 :(得分:5)

只需强制转换为matrix并使用prop.table的保证金参数,如下所示:

round( prop.table(as.matrix(df),2) * 100 , 3 )

例如

set.seed(123)
df <- data.frame( matrix( sample(4 , 12 , repl=TRUE ) , 3 ) )
df
#  X1 X2 X3 X4
#1  2  4  3  2
#2  4  4  4  4
#3  2  1  3  2
round( prop.table(as.matrix(df),2) * 100 , 3 )
#    X1     X2 X3 X4
#[1,] 25 44.444 30 25
#[2,] 50 44.444 40 50
#[3,] 25 11.111 30 25

在你的例子中,它看起来像我认为的rownames实际上是一列字符值。要在除第一个列之外的所有列上使用prop.table,您可以执行prop.table( df[,-1] , margin = 2 )

答案 1 :(得分:4)

不需要花哨的包装。只要您想要对除第一列以外的所有列执行此操作,这将起作用。如果2:ncol不合适,您可以调整包含哪些列的条件。

t(round(t(mydata[, 2:ncol(mydata)]) / colSums(mydata[, 2:ncol(mydata)]) * 100, 3))

而且,既然您询问了plyrdplyrddply的改进版本,那么您可以通过以下方式进行操作:

require(dplyr)
require(reshape2)

mydata %>% melt(id.vars = "label") %>%
    group_by(variable) %>%
    mutate(prop = round(value / sum(value) * 100, 3)) %>%
    dplyr::select(-value) %>%
    dcast(label ~ variable, fun.aggregate = sum, value.var = "prop")

将数据转换为长格式,计算比例,然后将其切换回宽。西蒙·奥汉隆(Simon O'Hanlon)所说的快速单行内容很多,但dplyr方法很好地概括了你可能想做的任何类型的计算。

答案 2 :(得分:2)

也许这样的事情可以帮到你:

cbind(label=mydat[,1],as.data.frame(apply(mydat[,-1], 2, function(col) round(prop.table(col),3)*100 )))

答案 3 :(得分:0)

你好,我有同样的问题

df1 <- head(mtcars[,c(1:2)],2)
sum(df1)

df <- round(as.data.frame(lapply(df1,function(x)x/sum(df1))),2); df;  class(df)

df <- as.data.frame(lapply(df, function(x) paste0(x,'%'))); df

mpg   cyl
1 0.39% 0.11%
2 0.39% 0.11%