循环内的线性模型(用于子集数据的循环)
Linear model within a loop (loop used to subset data)
我有(我认为应该是)R 中的一个直接问题,似乎无法让它工作。希望能帮到你。
我有一个数据框,例如:
x y z
1 2 a
2 3 a
3 4 a
4 5 b
5 6 b
6 7 b etc...
我正在为每个 z 值子集(例如 a、b...)拟合一个线性模型 (y ~ x) 并提取梯度。
当我 select 'a' 使用 with 语句时它有效:
coef(with(subset(data.frame, z == "a"), {lm(y ~ x)
}))[2]
但我的问题是我在 Z 列中有超过 1000 个唯一值。所以我尝试设置一个循环(我知道 R 用户讨厌循环!)依次对 z 的每个值执行此操作,并 return 数据框中的结果。代码是:
gradient.lm = NULL
unique.z <- as.matrix((unique(data.frame$z)))
count.z <- nrow(unique.z)
for (i in 1:count.z) {
gradient.lm[i] = coef((with(subset(data.frame, z == [i]), {lm(y ~ z)
})))[2]
}
但这不起作用,并给我错误代码:
> for (i in 1:count.z) {
+ activity.lm[i] = coef((with(subset(data.frame, z == [i]), {lm(y ~ x)
Error: unexpected '[' in:
"for (i in 1:count.z) {
activity.lm[i] = coef((with(subset(data.frame, z == ["
> })))[2]
Error: unexpected '}' in " }"
> }
Error: unexpected '}' in "}"
我的猜测是它没有意识到 with 函数中有一个 [i]。
我找不到实现此功能的方法,也找不到其他方法。如果您有任何建议,我们将不胜感激。
我强烈推荐 dplyr
和 broom
包解决方案:
set.seed(44)
dt = data.frame(x = rnorm(40, 5, 5),
y = rnorm(40, 3, 4),
z = rep(c("a","b"), 20))
library(dplyr)
library(broom)
dt %>%
group_by(z) %>% # group by column z
do(tidy(lm(y~x, data=.))) # for each group create model using corresponding x and y values
# Source: local data frame [4 x 6]
# Groups: z [2]
#
# z term estimate std.error statistic p.value
# (fctr) (chr) (dbl) (dbl) (dbl) (dbl)
# 1 a (Intercept) 3.54448459 1.8162699 1.9515186 0.06673401
# 2 a x -0.18140655 0.2260252 -0.8025944 0.43267918
# 3 b (Intercept) 1.69024601 1.1960922 1.4131402 0.17467413
# 4 b x 0.02647677 0.1914492 0.1382966 0.89154143
您可以提取您想要的 lm
输出的任何信息。
这似乎有效:
unique_z = unique(df$z)
coef_vec = vector(mode = "list", length = length(unique_z))
coef_vec[1] =
for (i in unique_z){
coef_vec[i] =
coef(
with(
subset(df, z==i),
{lm(y~x)}))[2]
}
print(coef_vec)
Cleary coef_vec[i]
对应于 unique_z[i]
中的 z 值,因此您的系数与其 z
值相匹配。
在 base-R 中,为您提供一个仅包含您显然感兴趣的梯度的命名向量:
gradient.lm <- unlist(lapply(split(df,df$z),function(chunk){
return(coef(lm(y~x, data=chunk))[[2]])
}))
我有(我认为应该是)R 中的一个直接问题,似乎无法让它工作。希望能帮到你。
我有一个数据框,例如:
x y z
1 2 a
2 3 a
3 4 a
4 5 b
5 6 b
6 7 b etc...
我正在为每个 z 值子集(例如 a、b...)拟合一个线性模型 (y ~ x) 并提取梯度。
当我 select 'a' 使用 with 语句时它有效:
coef(with(subset(data.frame, z == "a"), {lm(y ~ x)
}))[2]
但我的问题是我在 Z 列中有超过 1000 个唯一值。所以我尝试设置一个循环(我知道 R 用户讨厌循环!)依次对 z 的每个值执行此操作,并 return 数据框中的结果。代码是:
gradient.lm = NULL
unique.z <- as.matrix((unique(data.frame$z)))
count.z <- nrow(unique.z)
for (i in 1:count.z) {
gradient.lm[i] = coef((with(subset(data.frame, z == [i]), {lm(y ~ z)
})))[2]
}
但这不起作用,并给我错误代码:
> for (i in 1:count.z) {
+ activity.lm[i] = coef((with(subset(data.frame, z == [i]), {lm(y ~ x)
Error: unexpected '[' in:
"for (i in 1:count.z) {
activity.lm[i] = coef((with(subset(data.frame, z == ["
> })))[2]
Error: unexpected '}' in " }"
> }
Error: unexpected '}' in "}"
我的猜测是它没有意识到 with 函数中有一个 [i]。
我找不到实现此功能的方法,也找不到其他方法。如果您有任何建议,我们将不胜感激。
我强烈推荐 dplyr
和 broom
包解决方案:
set.seed(44)
dt = data.frame(x = rnorm(40, 5, 5),
y = rnorm(40, 3, 4),
z = rep(c("a","b"), 20))
library(dplyr)
library(broom)
dt %>%
group_by(z) %>% # group by column z
do(tidy(lm(y~x, data=.))) # for each group create model using corresponding x and y values
# Source: local data frame [4 x 6]
# Groups: z [2]
#
# z term estimate std.error statistic p.value
# (fctr) (chr) (dbl) (dbl) (dbl) (dbl)
# 1 a (Intercept) 3.54448459 1.8162699 1.9515186 0.06673401
# 2 a x -0.18140655 0.2260252 -0.8025944 0.43267918
# 3 b (Intercept) 1.69024601 1.1960922 1.4131402 0.17467413
# 4 b x 0.02647677 0.1914492 0.1382966 0.89154143
您可以提取您想要的 lm
输出的任何信息。
这似乎有效:
unique_z = unique(df$z)
coef_vec = vector(mode = "list", length = length(unique_z))
coef_vec[1] =
for (i in unique_z){
coef_vec[i] =
coef(
with(
subset(df, z==i),
{lm(y~x)}))[2]
}
print(coef_vec)
Cleary coef_vec[i]
对应于 unique_z[i]
中的 z 值,因此您的系数与其 z
值相匹配。
在 base-R 中,为您提供一个仅包含您显然感兴趣的梯度的命名向量:
gradient.lm <- unlist(lapply(split(df,df$z),function(chunk){
return(coef(lm(y~x, data=chunk))[[2]])
}))