group_by() 中的 mutate() 中的 lm()
lm() within mutate() in group_by()
我正在寻找一种方法来向我的数据 table 添加一个列,该列由 lm(a~b)
函数中的 residuals
组成,该函数针对 [=15= 的不同级别分别计算]
有人建议我查看 sort_by(c)
函数,但这似乎不适用于 lm(a~b)
我的工作示例数据如下所示:
subject、trial 和 rt 列在 data.frame
内,我的目标是计算 Zre_SPSS
(我最初是在 SPSS 中创建的)但是来自 R
函数。
我试过了
data %<>% group_by (subject) %>%
mutate(Zre=residuals(lm(log(rt)~trial)))
但它不起作用 - Zre 得到计算但不是在每个主题内单独计算,而是针对整个数据框。
谁能帮帮我?我是一个完整的 R(和一般编码)新手,所以如果这个问题很愚蠢或 duplicate,请原谅我,很可能我不理解其他解决方案或者他们不是我寻找的解决方案。最好的祝福。
根据 Ben Bolker 的要求,这里是从 excel 屏幕截图
生成数据的 R 代码
#generate data
subject<-c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3)
subject<-factor(subject)
trial<-c(1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6)
rt<-c(300,305,290,315,320,320,350,355,330,365,370,370,560,565,570,575,560,570)
#Following variable is what I would get after using SPSS code
ZreSPSS<-c(0.4207,0.44871,-1.7779,0.47787,0.47958,-0.04897,0.45954,0.45487,-1.7962,0.43034,0.41075,0.0407,-0.6037,0.0113,0.61928,1.22038,-1.32533,0.07806)
#make data frame
sym<-data.frame(subject, trial, rt, ZreSPSS)
这看起来像是 dplyr 0.5 mutate
中的错误,其中组内的 lm
仍会尝试使用完整数据集。您可以使用 do
代替:
sym %>% group_by(subject) %>% do(
{
r <- resid(lm(log(rt) ~ trial, data = .))
data.frame(., r)
})
这仍然与您的 SPSS 列不匹配,但它是您提供的数据的正确结果。您可以通过为每个受试者手动拟合模型并检查残差来验证这一点。
(其他类型的残差包括 rstandard
用于标准化残差和 rstudent
用于学生化残差。它们仍然与您的 SPSS 数字不匹配,但可能是您正在寻找的。)
更高版本的 dplyr
似乎能够处理这个(使用 dplyr
0.7.4 测试):
sym %>% group_by(subject) %>% do(
{
r <- resid(lm(log(rt) ~ trial, data = .))
data.frame(., r)
}) ->a
sym %>% group_by(subject) %>% mutate(
r = resid(lm(log(rt) ~ trial))
) ->b
all(a$r==b$r) #->TRUE
另一个独立测试
#
#
# https://github.com/tidyverse/dplyr/issues/2177
# tested with dplyr 0.7.4
# 1) do
df = group_by(iris,Species) %>% do({
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=.) )
data.frame(., res)
})
# 2) group_by + mutate
# cannot have "data=." in lm
df2 = group_by(iris,Species) %>% mutate(
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width) )
)
# 3) filter + mutate
df3 = filter(iris,Species=='setosa') %>% mutate(
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=.) )
)
df3 = bind_rows(df3,
filter(iris,Species=='versicolor') %>% mutate(
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=.) )
))
df3 = bind_rows(df3,
filter(iris,Species=='virginica') %>% mutate(
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=.) )
))
# 4) across all rows (should not be the same)
df4 = mutate(iris,
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=iris) )
)
# conclusion: all the same, except df4
all(df$res==df2$res)
all(df$res==df3$res)
df$res==df4$res
我正在寻找一种方法来向我的数据 table 添加一个列,该列由 lm(a~b)
函数中的 residuals
组成,该函数针对 [=15= 的不同级别分别计算]
有人建议我查看 sort_by(c)
函数,但这似乎不适用于 lm(a~b)
我的工作示例数据如下所示:
subject、trial 和 rt 列在 data.frame
内,我的目标是计算 Zre_SPSS
(我最初是在 SPSS 中创建的)但是来自 R
函数。
我试过了
data %<>% group_by (subject) %>%
mutate(Zre=residuals(lm(log(rt)~trial)))
但它不起作用 - Zre 得到计算但不是在每个主题内单独计算,而是针对整个数据框。
谁能帮帮我?我是一个完整的 R(和一般编码)新手,所以如果这个问题很愚蠢或 duplicate,请原谅我,很可能我不理解其他解决方案或者他们不是我寻找的解决方案。最好的祝福。
根据 Ben Bolker 的要求,这里是从 excel 屏幕截图
生成数据的 R 代码#generate data
subject<-c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3)
subject<-factor(subject)
trial<-c(1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6)
rt<-c(300,305,290,315,320,320,350,355,330,365,370,370,560,565,570,575,560,570)
#Following variable is what I would get after using SPSS code
ZreSPSS<-c(0.4207,0.44871,-1.7779,0.47787,0.47958,-0.04897,0.45954,0.45487,-1.7962,0.43034,0.41075,0.0407,-0.6037,0.0113,0.61928,1.22038,-1.32533,0.07806)
#make data frame
sym<-data.frame(subject, trial, rt, ZreSPSS)
这看起来像是 dplyr 0.5 mutate
中的错误,其中组内的 lm
仍会尝试使用完整数据集。您可以使用 do
代替:
sym %>% group_by(subject) %>% do(
{
r <- resid(lm(log(rt) ~ trial, data = .))
data.frame(., r)
})
这仍然与您的 SPSS 列不匹配,但它是您提供的数据的正确结果。您可以通过为每个受试者手动拟合模型并检查残差来验证这一点。
(其他类型的残差包括 rstandard
用于标准化残差和 rstudent
用于学生化残差。它们仍然与您的 SPSS 数字不匹配,但可能是您正在寻找的。)
更高版本的 dplyr
似乎能够处理这个(使用 dplyr
0.7.4 测试):
sym %>% group_by(subject) %>% do(
{
r <- resid(lm(log(rt) ~ trial, data = .))
data.frame(., r)
}) ->a
sym %>% group_by(subject) %>% mutate(
r = resid(lm(log(rt) ~ trial))
) ->b
all(a$r==b$r) #->TRUE
另一个独立测试
#
#
# https://github.com/tidyverse/dplyr/issues/2177
# tested with dplyr 0.7.4
# 1) do
df = group_by(iris,Species) %>% do({
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=.) )
data.frame(., res)
})
# 2) group_by + mutate
# cannot have "data=." in lm
df2 = group_by(iris,Species) %>% mutate(
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width) )
)
# 3) filter + mutate
df3 = filter(iris,Species=='setosa') %>% mutate(
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=.) )
)
df3 = bind_rows(df3,
filter(iris,Species=='versicolor') %>% mutate(
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=.) )
))
df3 = bind_rows(df3,
filter(iris,Species=='virginica') %>% mutate(
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=.) )
))
# 4) across all rows (should not be the same)
df4 = mutate(iris,
res = resid( lm(Sepal.Length~Petal.Length+Petal.Width, data=iris) )
)
# conclusion: all the same, except df4
all(df$res==df2$res)
all(df$res==df3$res)
df$res==df4$res