繁体   English   中英

For 循环跨多个列

[英]For loop across multiple columns

我有一些问卷数据,用于衡量进入商店的频率(“_freq”)和体验的享受(“_enj”)。 总共有 17 家商店(shop1、shop2、...)和 120 行数据。 下面是仅商店 1 和 2 的 5 行数据的示例。

shop1_freq shop1_enj shop2_freq shop2_enj
0 9 5 4
3 2 0 9
0 9 5 4
0 2 0 9
4 9 5 4

我编写了一个 for 循环,它将对问卷的错误回答标记为“999”,以便我可以识别它们。 基本上,对于每个孤立的商店,如果频率为 0 并且享受不是9,则响应不正确,或者如果频率不是0 但享受为 9,则响应不正确。目前我正在重复 17 次以下的循环(个人为每个商店,下面只是商店1)。

for (rows in 1:120){  
  if(data$shop1_freq[rows] == "0" & data$shop1_enj[rows] != 9) { 
    data$shop1_enj[rows] = "999" # label incorrect 999
  }
}

for (rows in 1:120){  
  if(data$shop1_freq[rows] != "0" & data$shop1_enj[rows] == 9) { 
    data$shop1_enj[rows] = "999" # label incorrect 999
  }
}

但是我想知道是否有一种更有效的方法可以用更少的代码为所有 17 家商店做到这一点?

对于多个 'shop_\d+_enj' 列及其对应的 '_freq' 列,它可以across mutate中完成

library(dplyr)
data1 <- data %>%
    mutate(across(matches('^shop\\d+_enj$'), ~ {
             tmp <- get(str_replace(cur_column(), '_enj', '_freq'))
             case_when(tmp == 0 &  . != 9 ~ 999, 
                       tmp != 0 & . == 9 ~ 999,
                    TRUE ~ .)

      }))

细节 -

我们遍历匹配 'shop' across列,后跟一个或多个数字,然后是列名中的_和 'enj',通过替换列名 ( get cur_column() ) 后缀' _enj' 和 '_freq',使用它在case_when中使用逻辑运算符创建复合条件表达式,如果值为 TRUE,则将 ( ~ ) 这些行元素分配给 999,并在最后一个TRUE ~. . 在这里, . 是列值


base R中,这可以通过多种方式完成。 一种选择是根据列名的模式将数据拆分为list

lst1 <- split(data1, sub("_.*", "", names(data1))
out <- do.call(cbind, lapply(lst1, function(x) {
       x[[2]] <- ifelse(x[[1]] == 0 & x[[2]] != 9, 999,
     ifelse(x[[1]] != 0 & x[[2]] == 9, 999, x[[2]])))
     x 
     }))
                    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM