我有一个不同地点、年份和最高温度的数据框。我想对每个特定站点的温度和年份进行线性回归。如果我可以编写一个 for 循环,将相同的线性回归模型分别应用于所有站点,并给我一个包含站点名称的输出,而不是对每个站点都这样做,那就太好了。我做了一些虚拟数据,我在实际 df 中有 25 个站点。
data<- data.frame(site= c('alder','alder','alder','alder','alder','alder','alder','alder', 'oak','oak','oak','oak','oak','oak','oak','oak' ),
year= c('2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015','2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015'),
temp= c(0.5,3, 12, 42, 67, 8, 12, 22, 11, 4, 3, 6, 76, 1, 11, .9))
到目前为止,我是如何尝试这样做的:
output<- vector("list", length(unique(data$site)))
sites<- unique(data$site)
for (i in sites) {
data %>% filter(site=i) =j
lm(formula = temp~year, data = j)=k
output[[i]]=k
}
我不确定让 for 循环调用对应于一个站点的行子集的最佳方法是什么。当我运行这段代码时,我得到的错误是
Error in data %>% filter(site = i) <- j :
could not find function "%>%<-"
我已经确定 tidyverse 在我的图书馆里
感谢您的帮助!
有几个错别字,
=
会是==
并做->
而不是=
。第三个问题是对 [[i]]
的分配 - 这里 i
是每个站点的值。因此,我们可能需要命名output
以获得正确的分配
names(output) <- sites
for (i in sites) {
data %>% filter(site==i) -> j
lm(formula = temp~year, data = j)-> k
output[[i]]=k
}
-输出
> output
$alder
Call:
lm(formula = temp ~ year, data = j)
Coefficients:
(Intercept) year2009 year2010 year2011 year2012 year2013 year2014 year2015
0.5 2.5 11.5 41.5 66.5 7.5 11.5 21.5
$oak
Call:
lm(formula = temp ~ year, data = j)
Coefficients:
(Intercept) year2009 year2010 year2011 year2012 year2013 year2014 year2015
1.100e+01 -7.000e+00 -8.000e+00 -5.000e+00 6.500e+01 -1.000e+01 -3.263e-15 -1.010e+01
有了
tidyverse
,我们可以通过几种方式做到这一点
library(dplyr)
library(tidyr)
data %>%
nest_by(site) %>%
mutate(model = list(lm(temp ~ year, data = data))) %>%
ungroup
# A tibble: 2 × 3
site data model
<chr> <list<tibble[,2]>> <list>
1 alder [8 × 2] <lm>
2 oak [8 × 2] <lm>
或者使用
reframe
# dplyr version >= 1.1.0
data %>%
reframe(model = list(lm(temp ~year)), .by = site) %>%
as_tibble
-输出
# A tibble: 2 × 2
site model
<chr> <list>
1 alder <lm>
2 oak <lm>
使用基数R:
lapply(split(data[, c("year", "temp")], data[, "site"]),
function(x) lm(temp ~ year, data=x))