我想创建一个函数(最好带有apply
族函数,它在数据框中两个独立变量的数据子集上运行lm
函数。作为参考,我的数据是目前的结构如下(这是一个虚拟数据框,通常代表我正在使用的实际数据框):
District = c(rep("A", times = 25),
rep("B", times = 25),
rep("C", times = 25),
rep("D", times = 25))
Year = c(1971:1975, 1971:1975, 1971:1975, 1971:1975,
1971:1975, 1971:1975, 1971:1975, 1971:1975,
1971:1975, 1971:1975, 1971:1975, 1971:1975,
1971:1975, 1971:1975, 1971:1975, 1971:1975,
1971:1975, 1971:1975, 1971:1975, 1971:1975)
Crop = c(rep("Wheat", times = 5),
rep("Maize", times = 5),
rep("Rice", times = 5),
rep("Barley", times = 5))
set.seed(100)
Yield = rnorm(100, 2, 0.5)
df <- data.frame(District, Year, Crop, Yield)
我需要生成一个线性模型(lm
),预测Yield
作为Year
的函数,每个Crop
基于District
。所以,我需要每个地区的小麦模型,每个地区的大麦,等等。我需要尽可能地自动化这个,因为我的真实数据将产生大约7000个线性模型。
我this answer James Bond发现作为出发点非常有帮助。它非常优雅并且使用lapply
,如果可能的话我也想做(7000线性模型=非常慢)。但是,它只是在数据集中对SINGLE列进行子集化,而我需要为每个模型子集两个变量。这是我当前(非工作)代码修改为在上面的虚拟数据集上运行:
df$Dist <- as.factor(df$Dist)
df$Crop <- as.factor(df$Crop)
for (i in 1:length(levels(df$Crop))) {
x <- levels(df$Crop)[i]
dat <- df[df$Crop == x, ]
out <- lapply(levels(dat$Dist), function(z) {
data.frame(District = z,
Slope = lm(Yield ~ Year, data = dat[dat$Dist == z, ])$coef[2],
Crop = x,
row.names=NULL)
})
}
do.call(rbind ,out)
不幸的是,运行上面的代码只会为数据集(Wheat)中的第一个Crop
级别生成一个模型。请参阅以下输出:
District Slope Crop
1 A 0.03125866 Wheat
2 B -0.08108222 Wheat
3 C 0.17172314 Wheat
4 D -0.11278486 Wheat
我们非常感谢能够遍历Crop
和District
变量的任何帮助。看起来我很接近,但似乎错过了关于for循环的一些基本信息。
如果可以将2个参数传递给lapply
函数并完全避免for
循环,那将是惊人的。提前谢谢!
答案 0 :(得分:2)
使用 dplyr 的一个选项:
df_lm <- df %>%
group_by(District,Crop) %>%
do(mod = lm(Yield ~ Year,data = .))
df_coef <- df_lm %>%
do(data.frame(
District = .$District,
Crop = .$Crop,
var = names(coef(.$mod)),
coef(summary(.$mod)))
)
> df_coef
Source: local data frame [32 x 7]
Groups: <by row>
# A tibble: 32 × 7
District Crop var Estimate Std..Error t.value Pr...t..
* <fctr> <fctr> <fctr> <dbl> <dbl> <dbl> <dbl>
1 A Barley (Intercept) -407.66953514 378.49788671 -1.0770722 0.36034462
2 A Barley Year 0.20771336 0.19183872 1.0827499 0.35818046
3 A Maize (Intercept) 159.81133118 212.90233600 0.7506321 0.50738515
4 A Maize Year -0.08002266 0.10790790 -0.7415830 0.51211787
5 A Rice (Intercept) -68.01125454 117.60578244 -0.5782986 0.60361684
6 A Rice Year 0.03552764 0.05960758 0.5960255 0.59313364
7 A Wheat (Intercept) -59.61828825 134.67806297 -0.4426726 0.66972726
8 A Wheat Year 0.03125866 0.06826053 0.4579317 0.65918309
9 B Barley (Intercept) -319.99755207 57.14553545 -5.5996947 0.01125215
10 B Barley Year 0.16332436 0.02896377 5.6389189 0.01103509
# ... with 22 more rows
另一件需要注意的是 nlme 中的lmList
功能。