【问题标题】:Loop over many outcome variables - Synth() package in R循环许多结果变量 - R 中的 Synth() 包
【发布时间】:2018-10-21 04:52:34
【问题描述】:

我在 R 中使用 Synth() 包(参见 ftp://cran.r-project.org/pub/R/web/packages/Synth/Synth.pdf)。

这是我的数据框的一个子集:

all_data_uk <- structure(list(countryno = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 16, 16, 
16), country = c("Australia", "Australia", "Australia", "Canada", 
"Canada", "Canada", "Denmark", "Denmark", "Denmark", "United Kingdom", 
"United Kingdom", "United Kingdom"), year = c(1971, 1972, 1973, 
1971, 1972, 1973, 1971, 1972, 1973, 1971, 1972, 1973), top10_income_share = c(0.2657, 
0.2627, 0.2546, 0.37833, 0.37807, 0.37271, 0.323069660453, 0.322700285165, 
0.320162826601, 0.2929, 0.289, 0.2831), top5_income_share = c(0.1655, 
0.1654, 0.1593, 0.24075, 0.24106, 0.23917, 0.211599113574, 0.21160700537, 
0.209096813051, 0.1881, 0.1848, 0.1818), top1_income_share = c(0.0557, 
0.0573, 0.054, 0.08866, 0.08916, 0.08982, 0.082392548404, 0.0824267594074, 
0.07776546085945, 0.0702, 0.0694, 0.0699), gdp_growth =     structure(c(4.00330835508684, 
3.91178191457604, 2.59931282534502, 4.11765761702448, 5.44585557970514, 
6.96420291945871, 3.00503299618597, 3.92934382503836, 4.09292523611968, 
3.48436803631409, 4.30194591910262, 6.50872079327365), label = "(annual %)", class = c("labelled", 
"numeric")), capital_quinn = structure(c(50, 37.5, 37.5, 87.5, 87.5, 75, 75, 75, 75, 50, 50, 50), label = "(financial openness - capital     account)", class = c("labelled", 
"numeric"))), class = "data.frame", .Names = c("countryno", "country", 
   "year", "top10_income_share", "top5_income_share", "top1_income_share", 
"gdp_growth", "capital_quinn"), row.names = c(NA, -12L))

在我的可重现示例中,我有三个不同的结果变量“top10_income_share”、“top5_income_share”、“top1_income_share”(在我的实际问题中我有更多),我想用它们来运行分析。 “gdp_growth”和“capital_quinn”是我的控制变量。

对于一个结果变量,这里是“top10_income_share”,我有以下代码(可以正常工作):

# Define treated and control units
control_units_top10 <- c(1,2)
treated_unit <- 16

# Run dataprep() which returns a list of matrices
dataprep.out_top10 <- dataprep(
  foo = all_data_uk,
  predictors = c("gdp_growth", "capital_quinn"),
  predictors.op = "mean", 
  time.predictors.prior = 1971:1972,
  special.predictors = list(
    list("top10_income_share", 1971, "mean"),
    list("top10_income_share", 1972, "mean")),
  dependent = "top10_income_share",
  unit.variable = "countryno",
  unit.names.variable = "country",
  time.variable = "year",
  treatment.identifier = treated_unit,
  controls.identifier = control_units_top10,
  time.optimize.ssr = 1971:1972,
  time.plot = 1971:1973)

# Run synth() command
synth.out_top10 <- synth(data.prep.obj = dataprep.out_top10, optimxmethod = "BFGS")

# Annual discrepancies in the top 10 income share trend between unit 4 (United Kingdom) and its synthetic counterpart:
gaps_top10 <- dataprep.out_top10$Y1plot - (dataprep.out_top10$Y0plot %*% synth.out_top10$solution.w)

我想遍历这些命令并对所有三个结果变量进行相同的分析。我的问题是,每次我都必须调整treatment.identifierspecial.predictorsdependent。此外,我想存储所有三个结果变量的输出(dataprep.out_top10、dataprep.out_top5...;synth.out_top10、synth.out_top5...等)。

我发现了一个类似的问题 (Save every R for loop iteration in a new list),但是他们在每个循环中都有相同的结果和控制变量,只想循环控制单元,我没有成功地将他们的解决方案应用于我的问题。

以下是我目前想出的:

control_units_top10 <- c(1,2)
control_units_top5 <- c(1,2,3)
control_units_top1 <- c(1,3)
treated_unit <- 16

for(top in c("top10", "top5", "top1"))   
{
  paste0("dataprep.out_", top) <- dataprep(
    foo = all_data_uk,
    predictors = c("gdp_growth", "capital_quinn"),
    predictors.op = "mean", 
    time.predictors.prior = 1971:1972,
    special.predictors = list(
      list(paste0(top, "_income_share"), 1971, "mean"),
      list(paste0(top, "_income_share"), 1972, "mean")),
    dependent = paste0(top, "_income_share"),
    unit.variable = "countryno",
    unit.names.variable = "country",
    time.variable = "year",
    treatment.identifier = treated_unit,
    controls.identifier = get(paste0("control_units_", top)),
    time.optimize.ssr = 1971:1972,
    time.plot = 1971:1973)

  paste0("synth.out_", top) <- synth(data.prep.obj = dataprep.out, optimxmethod = "BFGS")

  paste0("gaps_", top) <- paste0("dataprep.out_", top)$Y1plot - (paste0("dataprep.out_", top)$Y0plot %*% paste0("synth.out_", top)$solution.w)
}

我收到错误:Error in paste0("synth.out_", top) &lt;- synth(data.prep.obj = dataprep.out, : target of assignment expands to non-language object,所以我猜我的 paste0() 方法不起作用,但我找不到任何其他解决方案来“索引”结果变量和我的新对象。

我是 R 和 stockoverflow 的新手,如果有任何关于如何设置循环的提示,我会非常高兴。

提前谢谢你!

【问题讨论】:

    标签: r for-loop lapply


    【解决方案1】:

    我想我明白了。
    它有点长,但这主要是因为我选择以与您所做的类似的方式将其拼凑起来。当然可以将事情浓缩并在一个循环中运行整个事情。

    library(Synth)
    
    # Create a vector of variable names
    cnames <- colnames(all_data_uk)
    outcome_var <- cnames[grepl("income_share", cnames)]
    
    # Creating a 'wrapper function' for dataprep().
    # Purely out of convenience, so we don't have to think about all
    # the arguments that will stay the same.
    prepfun <- function(VAR, control_units, treated_unit) {
        dataprep(
        foo = all_data_uk,
        predictors = c("gdp_growth", "capital_quinn"),
        predictors.op = "mean", 
        time.predictors.prior = 1971:1972,
        special.predictors = list(
          list(VAR, 1971, "mean"),
          list(VAR, 1972, "mean")),
        dependent = VAR,
        unit.variable = "countryno",
        unit.names.variable = "country",
        time.variable = "year",
        treatment.identifier = treated_unit,
        controls.identifier = control_units,
        time.optimize.ssr = 1971:1972,
        time.plot = 1971:1973)
    }
    
    # Define treated and control units
    treated_unit <- 16
    control_units_top10 <- c(1,2)
    control_units_top5 <- c(1,2,3)
    control_units_top1 <- c(1,3)
    control_list <- list(control_units_top10, control_units_top5, control_units_top1)
    
    # Run dataprep() in a loop over both the variable names, and the list of
    # control unit specifiers, returning a list of lists
    dataprep_list <- mapply(prepfun, outcome_var, control_list, treated_unit,
      SIMPLIFY=FALSE)
    
    # Run synth() command
    # In a loop over the dataprep list of lists
    synth.out_list <- lapply(dataprep_list, synth, optimxmethod = "BFGS")
    
    # simple summaries
    lapply(synth.out_list, "[[", "solution.w")
    lapply(synth.out_list, "[[", "solution.v")
    
    
    # Annual discrepancies in the top 10 income share trend between unit
    # 16 (United Kingdom) and its synthetic counterpart:
    
    # defining the discrepancy function
    discr <- function(y1, y0, sw) {
        y1 - (y0 %*% sw)
    }
    
    # getting a list of data and weights for each variable 
    y1_list <- lapply(dataprep_list, "[[", "Y1plot")
    y0_list <- lapply(dataprep_list, "[[", "Y0plot")
    sw_list <- lapply(synth.out_list, "[[", "solution.w")
    
    # mapply takes a single function and several lists of arguments
    discrepancies <- mapply(discr, y1_list, y0_list, sw_list, SIMPLIFY=FALSE)
    

    lapply()mapply() 函数将删除列名,因此如果您希望它们出现在最终结果中,您必须自己添加它们。

    discrepancies <- do.call(cbind, discrepancies)
    colnames(discrepancies) <- outcome_var
    discrepancies
    
    #      top10_income_share top5_income_share top1_income_share
    # 1971       0.0007806441      0.0016615564      0.0009574887
    # 1972      -0.0007620713     -0.0016525268     -0.0009905464
    # 1973       0.0007952133      0.0002760334      0.0011823801
    

    如果您对*apply() 函数有任何疑问,请尽管提问。我记得当我第一次开始使用 R 时,我很难理解它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-19
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      • 2020-01-08
      相关资源
      最近更新 更多