簡體   English   中英

將函數應用於R中數據幀的每一列內的組

[英]apply function to groups within each column of a data frame in R

我想按組計算大型數據幀的子集中的每一列的均值和標准差。

我試圖理解為什么對類似問題的某些答案對我不起作用; 我在R上還很陌生,我敢肯定我有很多微妙之處(不是那么微妙的東西!),我完全不見了。

我有一個與此相似的大數據框:

mydata <- data.frame(Experiment = rep(c("E1", "E2", "E3", "E4"), each = 9), 
                     Treatment = c(rep(c("A", "B", "C"), each = 3), rep(c("A", "C", "D"), each = 3), rep(c("A", "D", "E"), each = 3), rep(c("A", "B", "D"), each = 3)), 
                     Day1 = sample(1:100, 36), 
                     Day2 = sample(1:100, 36),
                     Day3 = sample(1:150, 36),
                     Day4 = sample(50:150, 36))

我需要按實驗和處理對數據進行子集化,例如:

testB <- mydata[(mydata[, "Experiment"] %in% c("E1", "E4")) 
            & mydata[, "Treatment"] %in% c("A", "B"), 
            c("Treatment", "Day1", "Day2", "Day4")]

然后,對於testB中的每一列,我想計算每個治療組的平均值和標准差。

我首先嘗試使用tapply(僅從一列開始),但是對於不應包含在testB中的治療組,請返回“ NA”,這對於這個小的數據集來說不是什么大問題,但是非常討厭用我的真實數據:

>tapply(testB$Day1, testB$Treatment, mean)
   A        B        C        D        E 
70.66667 61.00000       NA       NA       NA 

我嘗試為data.frame中的多個變量按組計算均值和標准差來實現解決方案。 使用匯總工作:

ag <- aggregate(. ~ Treatment, testB, function(x) c(mean = mean(x), sd = sd(x)))

但是我無法使data.table解決方案正常工作。

library(data.table)
testB[, sapply(.SD, function(x) list(mean=mean(x), sd=sd(x))), by = Treatment]
testB[, c(mean = lapply(.SD, mean), sd = lapply(.SD, sd)), by = Treatment]

都給我錯誤信息

Error in `[.data.frame`(testB, , c(mean = lapply(.SD, mean), sd = lapply(.SD,  : 
unused argument(s) (by = Treatment)

我究竟做錯了什么?

在此先感謝您幫助無知的初學者!

您的專欄是重要因素。 盡管您刪除了子集testB中具有“ C”,“ D”和“ E”處理的行,但是這些級別仍然存在。 使用level(testB)來查看它們。 定義testB子集時,可以使用droplevels函數,以使您能夠獲得A和B的均值,而無需為空因子水平返回NA。

testB <- droplevels(mydata[(mydata[, "Experiment"] %in% c("E1", "E4")) 
        & mydata[, "Treatment"] %in% c("A", "B"), 
        c("Treatment", "Day1", "Day2", "Day4")]
tapply(testB$Day1,testB$Treatment,mean)
   A        B 
59.16667 66.00000 

希望這可以幫助!

羅恩

您也可以使用plyrreshape2解決此問題; 我通常更喜歡使用這些庫,因為它們引入的抽象適用於更多問題,並且更干凈。

我將如何解決:

library(plyr)
library(reshape2)
# testB from your code above

# make a "long" version of testB
longTestB <- melt(testB, id.vars="Treatment")
# then use ddply for calculating your metrics
ddply(longTestB, .(Treatment), summarize, mean=mean(value), stdev=sd(value))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM