簡體   English   中英

應用函數而不是使用循環

[英]apply a function instead of using a loop

我已經在文檔和論壇中搜索了很長時間,但是我仍然很難理解如何使用apply函數而不是R中的循環來獲取更復雜的函數。 (對於諸如apply(data,1,sum)之類的函數,雖然可以)

例如我有以下功能

 AOV_GxT=function(Trial_group,trait,df){ 

        sub_table=df[which(df$Trial.group == Trial_group),]

        aov_GxT = anova(aov(sub_table[,trait] ~ Genotype + Treatment + Treatment/Rep.number + Genotype*Treatment, data=sub_table, na.action="na.omit"))

        pvalue = aov_GxT$"Pr(>F)"[2]
        return(c(Trial_group,trait,pvalue))  

    }

我想為數據Trial_groups df申請每個Trial_groups和每個traits (以Trial_groups單位)

所以我通常會執行以下操作(效果很好):

aov_table=data.frame(matrix(ncol=4))
colnames(aov_table)=c("Trial_group", "Trait", "pvalue G*T")
for(trait in colnames(dataset)[2:ncol(dataset)]){
  for(Trial_group in unique(dataset[,'Trial.group'])){
    aov_table<-cbind (aov_table,AOV_GxT(Trial_group,trait,dataset))  
  }

dataset是一個包含數據的數據框,而更多列則包含函數中aov的因子。

head(dataset)

     Trial.group     Trait1           Trait2           Trait3
          A        0.4709055        0.6123510        0.7098447
          B        0.4973123        0.6322532        0.7336145
          C        0.4955180        0.6243369        0.7336492
          D        0.4787380        0.6235426        0.7304343
          E        0.5137033        0.6418851        0.7364666
          F        0.4524246        0.5975655        0.7012825

我想限制使用的循環,並學習如何使用apply家庭功能,所以我創建列表,並試圖用mapply

trait_lst = list(colnames(df_vars_clean)[7:ncol(df_vars_clean)])
Tgrp_lst = list(unique(df_vars_clean[,'Trial.group']))

aov_table<-mapply(AOV_GxT(a,b,c),a=Tgrp_lst,b=trait_lst, c=dataset )

然后它給了我函數中的子集一個錯誤,我想是因為我嘗試從列表中做一個子集:

'buildin'類型的對象不可子集化

我知道我的代碼中可能存在一些錯誤,但是我是一個人學習R,並且有一些想法目前我不太了解。

如何在函數上使用apply而不是多個for循環?

謝謝。

正如評論中指出的那樣,ddply是一個不錯的選擇,但是,通過lapply也可以輕松解決該問題:

do.call(rbind, lapply(split(dataset, dataset$Trial.Group), function(tgDf) {
  do.call(rbind, lapply(c("Trait1", "Trait2", "Trait3"), function(trait) {
      ## you don't need the trial group, it is already subsetted.
      AOV_gtx(trait, tgDf)
  }))
}))

使用ddply可以刪除外部的lapply / split代碼:

ddply(dataset, "Trial.Group", function(tgDf) {
   ## the code in here would be the same, because you are iterating over
   ## the response cols.
})

所有這些功能(通常是R)的關鍵是不要預先分配數據結構來存儲結果-它具有功能,因此您將要構建結果然后返回它們。

暫無
暫無

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

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