2017-05-06 25 views
0

計算數據框中每列的平均值和標準偏差等值的最佳方法是什麼? 舉例來說,如果我有一個數據幀:使用for循環分別針對R中的不同類別執行操作

s <- data.frame(
    sample = c("s_1", "s_2", "s_3", "s_4", "s_5", "s_6", "s_7", "s_8"), 
    flavor = c("original", "chicken", "original", "original", "cheese", "chicken", "cheese", "original"), 
age = c(23, 25, 11, 5, 6, 44, 50, 2), 
    scale = c(4, 3, 2, 5, 4, 3, 1, 5)) 

如何使用for循環找到的均值和(例如,age)的基礎上另一列只有一個列的sd值(例如,flavor

我有代碼找到平均值和標準偏差,但想知道是否有一種方法來使用循環代替。

print(paste("mean =", 
       mean(s[s$flavor == "original", "age"]), 
       "sd =", 
       sd(s[s$flavor == "original", "age"]))) 
+0

所以我不必編寫略有不同三個碼,每個類別(味) 。 – Monique

+1

嘗試使用dplyr代替:'library(dplyr)',然後'%>%group_by(flavor)%>%summarize(mean = mean(age),sd = sd(age))' –

+1

[How to計算平均值,cv和標準偏差同時使用組中的R](http://stackoverflow.com/questions/28916810/how-to-compute-mean-cv-and-standard-deviation-simultaneously-using-by-group -在) – Uwe

回答

1

如果我們需要一個for循環,然後通過的「味道」的unique元素循環,子集基礎上的「味道」的值的「年齡」,並獲得mean和sd`爲每個類別設定被包括在矢量「V1」

v1 <- c() 
for(un1 in unique(s$flavor)){ 
    tmp <- s$age[s$flavor == un1] 
    v1 <- c(v1, paste("mean =", mean(tmp), "sd =", sd(tmp))) 
} 

v1 
#[1] "mean = 10.25 sd = 9.28708781050335" "mean = 34.5 sd = 13.4350288425444" 
#[3] "mean = 28 sd = 31.1126983722081" 

代替最初創建一個NULL矢量(v1 <- c()),我們也可以預先分配長度等於在「香料」獨特元件的長度的一個矢量(應該是比上述效率更高)

v1 <- numeric(length(unique(s$flavor))) 

在循環中改變 'V1 < - ' 以

nm1 <- unique(s$flavor) 
for(i in seq_along(unique(s$flavor))){ 
    tmp <- s$age[s$flavor == nm1[i] ] 
    v1[i] <-paste("mean =", mean(tmp), "sd =", sd(tmp)) 
    } 

但是可以做到這一點作爲一個組通過操作與base R

do.call(data.frame, aggregate(age~flavor, s, FUN = function(x) c(Mean = mean(x), SD= sd(x)))) 

或者更有效的方法與data.table

library(data.table) 
setDT(s)[, paste("mean =", mean(age), "sd =", sd(age)), flavor]$V1 
0

由於循環效率不高,你可以使用dplyr像守護神建議或使用plyr如下:

require(plyr) 
s.summary <- ddply(s, c("flavor"), summarise, 
    N= length(age), 
    mean= round(mean(age),2), 
    sd= round(sd(age),2), 
    se = round(sd/sqrt(N),2) 
) 
s.summary