对多个输入使用 reformulate

Using reformulate with multiple inputs

小问题:

使用 reformulate 我可以生成以下内容:

reformulate(sprintf('interaction(%s)', "Q50_1"))
~interaction(Q50_1)

如何在不将其添加到字符串“Q50_1”的情况下创建这样的内容:

~interaction(Q50_1, gender=="F")

我可以这样做,但我想将它们添加为单独的参数。

reformulate(sprintf('interaction(%s)', "Q50_1, gender=='F'"))
~interaction(Q50_1, gender == "F")

完整问题:

我正在使用调查包 svymean 生成加权数据的 SE 和交叉 table 频率。我正在为重新制定功能而苦苦挣扎。

这是我的数据:

data <- read_table2("Q50_1   Q50_2   Q38 Q90 pov gender  wgt id
yes   3   Yes NA   High    M   1.3 A
NA   4   No  2   Med F   0.4 B
no   2   NA 4   Low F   1.2 C
maybe   3   No  2   High    M   0.5 D
yes   NA   No  NA   High    M   0.7 E
no   2   Yes 3   Low F   0.56 F
maybe   4   Yes 2   Med F   0.9 G
")

创建设计对象:

design <- svydesign(id =~id,
                        weights  = ~wgt,
                        nest = FALSE,
                        data = data)

循环遍历列名称并生成要读入函数的适当格式的用户函数。示例 ["~interaction(Q50_1)"].

vars1 <- c("Q50_1", "Q38")

create_df<- function(design, vector_vars){
  
 
  # function to retrieve the weighted,  mean and se 
  myfun <- function(x){
    form <- reformulate(sprintf('interaction(%s)', x))
    cbind(as.data.frame(svymean(form, design, na.rm = T)))
  }
  

  
  final <- do.call(rbind, lapply(vector_vars, myfun))
  return(final) 
}

create_df(design, vars1)

这按预期工作:

                             mean        SE
interaction(Q50_1)maybe 0.2713178 0.1932617
interaction(Q50_1)no    0.3410853 0.2233323
interaction(Q50_1)yes   0.3875969 0.2331215
interaction(Q38)No      0.3669725 0.2130455
interaction(Q38)Yes     0.6330275 0.2130455

这是我之前运行:

svymean(~interaction(Q50_1), design, na.rm = T)

但现在我想更改格式,以便我可以 运行 与不同列的特定值进行交互。例如,要 运行 Q50_1 by Female:

svymean(~interaction(Q50_1, gender=="F"), design, na.rm = T)

结果输出:

为了使上述操作自动化,我尝试将变量“column”添加到上述函数中,这将添加到“form”对象中,但重新制定的行为并不像预期的那样。对我如何实现这一点有什么建议吗?

尝试向表单对象添加第二个规范

create_df_new<- function(design, vector_vars, column){
  
  # function to retrieve the weighted,  mean and se 
  myfun <- function(x){
    form <- reformulate(sprintf('interaction(%s)', x, column))
    cbind(as.data.frame(svymean(form, design, na.rm = T)))
  }
  

  final <- do.call(rbind, lapply(vector_of_vars, myfun))
  return(final) 
}

create_df_new(design, vars1, "gender==F")

fmt 应与传递给 sprintf 的参数数量相匹配。在 OP 的代码中,只有一个 %s,而输入是 'x' 和 'column'。此外,在构建公式时,"gender == F"'gender == "F"' 之间存在差异。前者可以检查 FALSE 值,而后者检查字符串“F”

library(survey)
create_df_new <- function(design, vector_vars, column){
  
  # function to retrieve the weighted,  mean and se 
  myfun <- function(x){
    form <- reformulate(sprintf('interaction(%s, %s)', x, column))
    cbind(as.data.frame(svymean(form, design, na.rm = TRUE)))
  }
  

  final <- do.call(rbind, lapply(vector_vars, myfun))
  return(final) 
}

create_df_new(design, vars1, 'gender=="F"')

-输出

                                                mean         SE
interaction(Q50_1, gender == "F")maybe.FALSE 0.09689922 0.10433556
interaction(Q50_1, gender == "F")no.FALSE    0.00000000 0.00000000
interaction(Q50_1, gender == "F")yes.FALSE   0.38759690 0.23312149
interaction(Q50_1, gender == "F")maybe.TRUE  0.17441860 0.17253314
interaction(Q50_1, gender == "F")no.TRUE     0.34108527 0.22333227
interaction(Q50_1, gender == "F")yes.TRUE    0.00000000 0.00000000
interaction(Q38, gender == "F")No.FALSE      0.27522936 0.19411565
interaction(Q38, gender == "F")Yes.FALSE     0.29816514 0.24925980
interaction(Q38, gender == "F")No.TRUE       0.09174312 0.09968017
interaction(Q38, gender == "F")Yes.TRUE      0.33486239 0.21984468