[英]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.