首页 > 解决方案 > R 中用于 SAS 中“by”语句的等效代码,用于在变量的不同级别上运行多个 ANOVA

问题描述

我想按位置运行每个物种总捕获量的线性模型。数据如下所示:

Location REP TRAP SpeciesID Total
A1 A1_1 A1_1_1 Calaingr 5.288462
A1 A1_1 A1_1_1 Carataed 1.057692
A1 A1_1 A1_1_1 Harpfulv 1.057692
…

该模型是一个非常简单的模型:C_AOV <- lmer(Total~Location + (1|REP))。所以我认为位置是固定效应,而代表是随机效应。

在 SAS 中,我可以使用“by”语句(通过 SpeciesID),​​它会告诉 SAS 为每个 SpeciesID 级别运行模型,因此输出 54 个单独的 ANOVA,每个物种一个。在 R 中是否有等效的方法来执行此操作?我尝试在网上寻找,但我没有遇到我能理解的方法。我确实看到了 plyr 包和一些示例,但不明白它们的作用。谢谢,某人

标签: rsas

解决方案


我可以为 R 说话,它比 SAS 过程中的 by 语句要冗长一些。通常,范式是拆分、应用、组合。您将至少有以下两个选项。假设您将数据存储为 df 对象。我实际上并没有运行任何代码。

Tidyverse 和扫帚

对于 '%>%' 管道运算符和 tidyverse 术语,这不会那么直观。但是,这可能是执行此操作的更简洁的方法之一。

# Not run    
library(tidyverse)

library(broom)

models <- df %>% 
 nest(-SpeciesID) %>% 
 mutate(fit = map(data, ~ lmer(Total~Location + (1|REP), data = .),
        results = map(fit, glance))%>%
 unnest(results)

models %>% select(-fit, -data)

拆分、应用、合并循环

恕我直言,循环结构使这更容易理解。

#Not run    
split <- split(df, SpeciesID)

models <- list()

for (i in 1:length(split)) {
 model_df <- split[[i]]
 models[[i]] <-  lmer(Total~Location + (1|REP), data=model_df)
}

sapply(1:length(models), function(x) {summary(models[[x]]})

基础 R 应用方法

这种方法非常简洁,并再次强调了 lmer 函数是如何“应用”在数据的各种子集上的。function(x) 是一个匿名函数,其中 x 是跨 df$SpeciesID 级别的迭代器。

by(df,df$SpeciesID, function(x) summary(lmer(Total~Location + (1|REP),data = x))) 

*来自Onyambu评论的解决方案

我敢肯定还有其他选择,但我希望这会有所帮助。作为从主要是 SAS 过渡到主要是 R 的人,这无疑是 SAS 使事情变得容易的事情之一。R 建模函数很少有类似于 SAS by 子句的参数。


推荐阅读