将许多 Stata 替换转移到 R

Transfer Many Stata Replaces to R

我有几千行 Stata 代码,通常旨在用来自同行的适当缺失值 (.) 替换负(缺失)值,我需要将此代码传输到 R。为此,我获取了代码并将其保存为一列字符串。替换基本上如下所示,令人作呕:

replace R04_ADULTTYPE = . if (R04_ADULTTYPE <= -1 )

这些R04_是数据集中的变量,所以我希望从本质上将Stata的这些行有效地转移到R中。

我已经尝试使用它和 separating/replacing 轻松迭代需要替换的变量列表,但我 运行 缺乏想法。 如果我有字符串数据集形式的这些替换,关于如何轻松地将它们全部转移到 R 有什么想法吗?我的预期输出基本上是在 R 中执行许多 Stata 替换,这我在下面提供了数据。

数据头部的Dput(rawMissing)。谢谢!

# Data (many Stata replaces
dput(head(rawMissing))
structure(list(replacements = c("replace R04_ADULTTYPE = . if (R04_ADULTTYPE <= -1 )", 
"replace R04R_A_AT0047 = . if (R04R_A_AT0047 <= -1 )", "replace R04R_A_AM0069 = . if (R04R_A_AM0069 <= -1 )", 
"replace R04R_A_AM0065_V2 = . if (R04R_A_AM0065_V2 <= -1 )", 
"replace R04_AM0066 = . if (R04_AM0066 <= -1 )", "replace R04_AM0070 = . if (R04_AM0070 <= -1 )"
)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))

# Expected output would be efficiently conducting these many replaces in R

我们可以extract将列名称、运算符和要替换的值作为单独的列

library(dplyr)
library(tidyr)
keydat <- rawMissing %>%
     extract(replacements, into = c('colnm', 'operator', 'value'), 
         '^[^(]+\((\w+)\s+([[:punct:]]+)\s+(-?[0-9]+)')

然后,使用上述数据,循环 across 原始数据集 'df1' 通过循环 across 在 'keydat' 中指定的列并执行 replace评论

df2 <- df1 %>%
   mutate(across(all_of(keydat$colnm), ~ 
         {
         op <- keydat$operator[match(cur_column(), keydat$colnm)]
         val <-  keydat$value[match(cur_column(), keydat$colnm)]
         replace(., match.fun(op)(., val), NA)
        


        }))

@akrun 的答案的替代方法是编写一个新的 R 脚本,然后获取该脚本的源代码。例如,这可能有助于查看代码并准确记录已完成的操作(例如,用于可复制的数据分析等)。我认为以下内容通常可以工作,其中 statareplace.do 是要读取的原始 Stata 文件的文件名,statareplace.R 是生成的 R 脚本的文件名:

fin <- "statareplace.do"
fout <- "statareplace.R"

f <- readLines(fin)
g <- gsub(
    "^\w+\s+(\w+)(\s+)?=(\s+)?.+if\((.+)\)$", "\1 = ifelse(\4", f
)
g <- gsub(
    "^\w+\s+(\w+)(\s+)?=(\s+)?(.+) if(\s+)?\((.+)\)$", 
    "\1 = ifelse(\6, \4, \1),", f
)
g <- gsub("\.", "NA", g)
g

writeLines(c("library(dplyr)", "df <- df %>%", "mutate(", g, ")"), fout)
source(fout)