我的猜测是使用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)
Run Code Online (Sandbox Code Playgroud)
这样做我可以一次将一个变量转换为百分比
mydata$var1 <- round(prop.table(mydata$var1),3)*100
Run Code Online (Sandbox Code Playgroud)
但是如何在一个笔划中的data.frame中使用所有变量(var1:var7)呢?
注意:它进入一个函数,其中变量的长度和数量不时变化,因此代码应该对此敏感.
先感谢您
只是胁迫a matrix并使用margin参数来prop.table这样:
round( prop.table(as.matrix(df),2) * 100 , 3 )
Run Code Online (Sandbox Code Playgroud)
例如
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
Run Code Online (Sandbox Code Playgroud)
在你的例子中,它看起来像我认为的rownames实际上是一列字符值.要prop.table在除第一个列之外的所有列上使用,您可以执行此操作prop.table( df[,-1] , margin = 2 ).
不需要花哨的包装。只要您想对除第一列之外的所有列执行此操作,此操作就有效。2:ncol如果不合适,您可以调整包含哪些列的条件。
t(round(t(mydata[, 2:ncol(mydata)]) / colSums(mydata[, 2:ncol(mydata)]) * 100, 3))
Run Code Online (Sandbox Code Playgroud)
而且,既然您询问了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")
Run Code Online (Sandbox Code Playgroud)
将数据转换为长格式,计算比例,然后将其切换回宽格式。西蒙·奥汉隆 (Simon O'Hanlon) 所展示的内容需要大量打字,但该dplyr方法可以很好地推广到您可能想要执行的任何类型的计算。