在 R 中的 for 循环内分组
Grouping inside of a for-loop in R
我正在使用在一篇科学论文中发现的修改后的分位数回归函数。 (来源:https://arxiv.org/pdf/2111.04805.pdf)
我尝试将此特定方法应用于我的数据集,但我想根据我的数据集中的条件执行此分位数回归。这意味着我想实现类似于 group_by 条件的东西,如下所示:
qr_models = data %>%
group_by(latitude) %>%
do(model = rq(julian_day~year, tau = 1:99/100, method = "fn", data= .))
论文中的编码方式如下,循环是我想添加 group_by:
for (i in 1:n) {
alpha = i/(n+1)
alphas[i] = alpha
betas <- smrq(X,y,tau=alpha)
vals0[i] <- sum(y<(X %*% betas))
}
其中 n 是 n <- 99
(选择的分位数分辨率); vals0 <- rep(0,n)
和 alphas <- rep(0,n)
。我倾向于避免在 R 中使用循环,所以我有点不知道如何去做。
为了以防万一需要理解,smrq()
函数是前面提到的论文中描述的函数,并且编码如下:
smrq <- function(X, y, tau){
p = ncol(X)
op.result <- optim(rep(0, p),
fn = minimize.logcosh,
method = 'BFGS',
X = X,
y = y,
tau = tau)
beta <- op.result$par
return (beta)
}
其中 X 是解释变量矩阵,y 是响应变量。
我希望它足够清楚,如果需要更多细节,我会很乐意更新我的 post。非常感谢宝贵的帮助。
考虑将作者的整个处理封装在一个 user-defined 方法中,该方法接收数据(swiss
来自作者)作为输入参数以及其他变量,包括公式(Fertility ~ .
来自作者)和回复列("Fertility"
来自作者)。
然后,使用 group_by
传递数据子集。此外,作者的 for
循环可以重构为矢量化循环,例如 sapply
或 vapply
,因为 return 是一个数字向量。
广义函数
minimize.logcosh <- function(par, X, y, tau) {
diff <- y-(X %*% par)
check <- (tau-0.5)*diff+(0.5/0.7)*logcosh(0.7*diff)+0.4
return(sum(check))
}
smrq <- function(X, y, tau){
p <- ncol(X)
op.result <- optim(
rep(0, p),
fn = minimize.logcosh,
method = 'BFGS',
X = X,
y = y,
tau = tau
)
beta <- op.result$par
return(beta)
}
run_smrq <- function(data, fml, response) {
x <- model.matrix(fml, data)[,-1]
y <- data[[response]]
X <- cbind(x, rep(1,nrow(x)))
n <- 99
betas <- sapply(1:n, function(i) smrq(X, y, tau=i/(n+1)))
# betas <- vapply(1:n, function(i) smrq(X, y, tau=i/(n+1)), numeric(1))
return(betas)
}
来电者
测试作者的例子
swiss <- datasets::swiss
smrq_models <- run_smrq(data=swiss, fml=Fertility~., response="Fertility")
dplyr
(使用group_map
)
smrq_models <- data %>%
group_by(latitude) %>%
group_map(~ run_smrq(data=., fml=julian_day~year, response="julian_day")
base
(使用 by
,tapply
的 object-oriented 包装器)
smrq_models <- by(
data,
data$latitude,
function(sub) run_smrq(data=sub, fml=julian_day~year, response="julian_day")
)
我正在使用在一篇科学论文中发现的修改后的分位数回归函数。 (来源:https://arxiv.org/pdf/2111.04805.pdf)
我尝试将此特定方法应用于我的数据集,但我想根据我的数据集中的条件执行此分位数回归。这意味着我想实现类似于 group_by 条件的东西,如下所示:
qr_models = data %>%
group_by(latitude) %>%
do(model = rq(julian_day~year, tau = 1:99/100, method = "fn", data= .))
论文中的编码方式如下,循环是我想添加 group_by:
for (i in 1:n) {
alpha = i/(n+1)
alphas[i] = alpha
betas <- smrq(X,y,tau=alpha)
vals0[i] <- sum(y<(X %*% betas))
}
其中 n 是 n <- 99
(选择的分位数分辨率); vals0 <- rep(0,n)
和 alphas <- rep(0,n)
。我倾向于避免在 R 中使用循环,所以我有点不知道如何去做。
为了以防万一需要理解,smrq()
函数是前面提到的论文中描述的函数,并且编码如下:
smrq <- function(X, y, tau){
p = ncol(X)
op.result <- optim(rep(0, p),
fn = minimize.logcosh,
method = 'BFGS',
X = X,
y = y,
tau = tau)
beta <- op.result$par
return (beta)
}
其中 X 是解释变量矩阵,y 是响应变量。
我希望它足够清楚,如果需要更多细节,我会很乐意更新我的 post。非常感谢宝贵的帮助。
考虑将作者的整个处理封装在一个 user-defined 方法中,该方法接收数据(swiss
来自作者)作为输入参数以及其他变量,包括公式(Fertility ~ .
来自作者)和回复列("Fertility"
来自作者)。
然后,使用 group_by
传递数据子集。此外,作者的 for
循环可以重构为矢量化循环,例如 sapply
或 vapply
,因为 return 是一个数字向量。
广义函数
minimize.logcosh <- function(par, X, y, tau) {
diff <- y-(X %*% par)
check <- (tau-0.5)*diff+(0.5/0.7)*logcosh(0.7*diff)+0.4
return(sum(check))
}
smrq <- function(X, y, tau){
p <- ncol(X)
op.result <- optim(
rep(0, p),
fn = minimize.logcosh,
method = 'BFGS',
X = X,
y = y,
tau = tau
)
beta <- op.result$par
return(beta)
}
run_smrq <- function(data, fml, response) {
x <- model.matrix(fml, data)[,-1]
y <- data[[response]]
X <- cbind(x, rep(1,nrow(x)))
n <- 99
betas <- sapply(1:n, function(i) smrq(X, y, tau=i/(n+1)))
# betas <- vapply(1:n, function(i) smrq(X, y, tau=i/(n+1)), numeric(1))
return(betas)
}
来电者
测试作者的例子
swiss <- datasets::swiss
smrq_models <- run_smrq(data=swiss, fml=Fertility~., response="Fertility")
dplyr
(使用group_map
)
smrq_models <- data %>%
group_by(latitude) %>%
group_map(~ run_smrq(data=., fml=julian_day~year, response="julian_day")
base
(使用 by
,tapply
的 object-oriented 包装器)
smrq_models <- by(
data,
data$latitude,
function(sub) run_smrq(data=sub, fml=julian_day~year, response="julian_day")
)