5

我的猜测是,使用 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

4 回答 4

5

只需强制 amatrix并使用 margin 参数来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

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

于 2013-06-05T22:55:06.240 回答
4

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

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

而且,由于您询问plyr并且dplyr是 的改进版本ddply,因此您可以这样做:

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方法很好地推广到您可能想做的任何类型的计算。

于 2013-06-05T22:51:21.067 回答
2

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

cbind(label=mydat[,1],as.data.frame(apply(mydat[,-1], 2, function(col) round(prop.table(col),3)*100 )))
于 2013-06-05T22:54:57.597 回答
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%
于 2020-11-08T08:00:18.180 回答