2013-06-05 79 views
5

我的猜測是,這是很容易使用ddply,但我仍然是R的新手,不能讓我的頭靠近它。如何使用ddply計算數據幀中每個單元格的百分比?

我有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 

但如何與所有的變量做(VAR1: var7)在一個data.frame一筆?

注意:它正在進入一個函數,其中變量的長度和數量隨時間而不同,因此代碼應該對此敏感。

預先感謝您

回答

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方法很好地適用於任何你可能想要做的計算。

+0

非常感謝。它工作完美 – Einnor

+0

@Einnor如果這回答了你的問題,你應該*考慮*(閱讀 - 沒有義務)接受它來顯示這個問題已被回答。我注意到你還沒有接受你的6個問題的任何答案。您可能想閱讀[** about **](http://stackoverflow.com/about)以瞭解SO的工作原理,以幫助您充分利用網站。 –

+0

@ Simon0101我不知道我應該接受答案。但會做:) – Einnor

2

也許這樣的事情可以幫助你:

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

這也可以,謝謝:) – Einnor

+0

你可以稍微簡化一下:'data.frame(mydata [1],lapply(mydata [-1],function(x)round(prop.table(x)* 100, 3)))' – thelatemail

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)

+0

謝謝,這也適用 – Einnor