我有一个迭代函数的嵌套循环,但我想避免运行嵌套循环。但是,我坚持执行一个将运行并保存输出的替代脚本。
下面是循环,以及运行完整脚本的其他有用信息。
# data
df = data.frame(y1 = sample(x=0L:1L, size=120, replace=TRUE),
y2 = sample(x=0L:1L, size=120, replace=TRUE),
x1 = sample(x=1L:3L, size=120, replace=TRUE),
x2 = sample(x=1L:3L, size=120, replace=TRUE),
x3 = sample(x=1L:3L, size=120, replace=TRUE),
wgt = sample(runif(120, min=.25, max=.70), replace=TRUE))
#the function
chi2_test <- function(...){
termlabels = sapply(substitute(...()), deparse)
form <- reformulate(termlabels=termlabels, response="wgt")
cross_table = xtabs(form, data=df)
chi2_test = chisq.test(cross_table, correct=TRUE)
return(list(crosstabs = cross_table,
chi2_test = chi2_test)
)
}
# dvs and ivs
dvars = names(df)[1:2]
ivars = names(df)[3:5]
combos = tidyr::crossing(dvars, ivars)
# the loop: where I need some help with
for (i in combos$dvars){
for (j in combos$ivars){
cat(i, "by", j)
print(chi2_test(df[, i], df[, j]))
}
}
不需要嵌套循环,因为完整的组合已经用
crossing
创建了。因此,只需遍历 combos
的行序列,提取与每一行对应的名称,基于此对 df
列进行子集化,并将输出分配给初始化的 list
,其长度与行数相同连击
out <- vector('list', nrow(combos))
names(out) <- do.call(paste, c(combos, sep = " by "))
for(i in seq_along(combos$dvars))
out[[i]] <- chi2_test(df[, combos$dvars[i]], df[, combos$ivars[i]])
-输出
> out[1]
$`y1 by x1`
$`y1 by x1`$crosstabs
df[, combos$ivars[i]]
df[, combos$dvars[i]] 1 2 3
0 10.926195 8.558175 6.373337
1 13.388605 8.971302 8.481009
$`y1 by x1`$chi2_test
Pearson's Chi-squared test
data: cross_table
X-squared = 0.12113, df = 2, p-value = 0.9412