首页 > 解决方案 > 循环R中的部分变量名称列表

问题描述

我有一个与药物列表相关的数据集,“酒精”、“大麻”、“烟草”、“摇头丸”、“可卡因”、“苯丙胺”、“迷幻药”等。在数据框中,df.

每个变量都有曾经使用过的变量(ever_[drug])、年份使用的变量( ) year_[drug]、上个月使用的变量( ),这些变量mth_[drug]按顺序回答。如果您对前一个时间范围回答“是”(即 2),则只会询问后一个时间范围。在每种情况下,“否”都是 1。我需要重新编码为一个整体变量,例如,my_[drug]值为 0(从未使用)、1(使用,去年未使用)、2(去年)、3(上个月)。

这仅适用于一个:

my_cannabis <-  ifelse(ever_cannabis == 1, 0, 
                ifelse(year_cannabis == 1, 1,
                ifelse(mth_cannabis == 1, 2, 3)))

如何遍历所有药物名称并my_[drug]为每个名称生成?

编辑 - 有一些数据:

structure(list
(ever_cannabis = c(2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 1L), 
year_cannabis = c(2L, 2L, 2L, 1L, 2L, NA, 2L, 1L, 1L, 1L, 1L, NA), 
mth_cannabis = c(2L, 2L, 2L, NA, 2L, NA, 1L, NA, NA, NA, NA, NA), 
ever_cocaine = c(1L, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 1L, 1L), 
year_cocaine = c(NA, 2L, NA, NA, NA, NA, 1L, NA, 1L, NA, NA, NA), 
mth_cocaine = c(NA, 2L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), 
class = "data.frame", row.names = c(NA, -12L))

(不完全确定我做对了)

作为参考,在Stata中它将是:

foreach v in cannabis tobacco mdma cocaine amphetamine lsd {
    gen my_`v' = 0
    replace my_`v' = 1 if ever_`v' == 2
    replace my_`v' = 2 if year_`v' == 2
    replace my_`v' = 3 if mth_`v' == 2
    }

解决了它:

list_drugs <- c( "cannabis", "tobacco", "mdma", "cocaine", "amphetamine", "methamphetamine", "lsd")

for(i in 1:length(list_drugs)) {
  cur_dn <- list(drugname = as.name(list_drugs[[i]]))
eval(parse(text = paste0("my_",cur_dn," <-  ifelse(ever_",cur_dn," == 1, 0,", 
                                "ifelse(year_",cur_dn," == 1, 1,", 
                                "ifelse(mth_",cur_dn," == 1, 2, 3)))")))
}

标签: r

解决方案


不太确定以下代码是否是您所期望的:

lst <- lapply(seq(ncol(df)/3), function(k) df[,3*k + (-2:0)])
r <- lapply(lst,function(x) apply(x, 1, function(v) {k <- which(as.vector(v)==1);ifelse(length(k)>0,k-1,3)}))
names(r) <- paste0("my_",unique(gsub(".*_(\\w+)","\\1",colnames(df))))
my_drug <- data.frame(r)

产生:

> my_drug
   my_cannabis my_cocaine
1            3          0
2            3          3
3            3          0
4            1          0
5            3          0
6            0          0
7            2          1
8            1          0
9            1          1
10           1          0
11           1          0
12           0          0

推荐阅读