首页 > 解决方案 > 如何使用调查包的 svyby 函数在多个列上进行循环?

问题描述

我一直在尝试很多方法,但我无法解决问题。我在这里这里这里找到了,但我无法让它们适应我的问题。

我想传递两个字符串向量的组合,其中“pop”的每个元素将与“territ”的每个元素组合,并通过数字向量(“enroll_lines”)传递“enroll”列的子集。所以,我想要在 svyby 函数内部进行三个迭代:两个在字符串向量上,一个在子集数字向量内迭代。

我想要一个数据框,其中包含设计对象“dclus1”上三个向量的所有结果组合。

预先感谢您的关注和努力。

data(api)
df <- apiclus1
df$pais <- 0
df$pop_tot <- 1

pop <- c("pop_tot", "stype", "awards")
territ <- c("pais","cname", "dname")
enroll_lines = c(355, 455, 555)

dclus1<-svydesign(id=~dnum, weights=~pw, data=df, fpc=~fpc)

svyloop <- function(vv1, vv2, dsgn, xx) {
  svyby( as.formula( paste0( "~" , vv1)) , by = as.formula( paste0( "~" , vv2)) , subset(dsgn, enroll < xx), svytotal , vartype = 'cv')
}
svyloop(pop, territ, dclus1, enroll_lines)
#Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) :  contrasts can be applied only to factors with 2 or more levels

sapply(dclus1, svyloop, pop, territ, enroll_lines)
#Even though keeping just columns with two or more leves, the column "enroll" is not found, as the message below returns:
#Error in subset.default(dsgn, enroll < xx) : object 'enroll' not found

我尝试过的另一种方法是在函数中放置一个“i”迭代。

jj <- 1:3
svyloop <- function(vv1, vv2,, xx, i) {
  svyby( as.formula( paste0( "~" , vv1[i])) , by = as.formula( paste0( "~" , vv2[i])) , subset(dclus1, enroll < xx[i]), svytotal , vartype = 'cv')
}
svyloop(pop, territ, enroll_lines, jj)
sapply(dclus1, svyloop, pop, territ, enroll_lines)

#Error in `contrasts<-`(` tmp \`, value = contr.funs[1 + isOF[nn]]) : contrasts 只能应用于具有 2 个或更多级别的因子

标签: rloopssurvey

解决方案


in 的第一个参数sapply是循环的,你不想迭代你的设计,dclus1而是迭代pop,territenroll_lines. 您的解决方案无法工作,因为您没有为您的svytable-function 提供设计对象。您可以使用多个sapplys 并且您的功能有效。简单但不优雅的解决方案:

sapply(pop, 
       function(x) sapply(territ, 
                          function(y) sapply(enroll_lines, function(z) 
                  svyloop(x, y, dclus1, z),
                  simplify = F),
             simplify = F),
         simplify = F)

通过这种方式,您可以获得表格的嵌套列表,并且可以以您喜欢的任何方式组合它们。

可能有更有效的解决方案,mapply但嵌套的 sapplys 也可以工作。


推荐阅读