用 "OR" 条件有条件地替换值的紧凑代码

Compact code for conditional replacement of values with an "OR" condition

我有一个很长的数据集和一个相对较短的 ID 值列表,我的数据是错误的。 以下是有效的,但我的 wrong_IDs 向量实际上要大得多:

wrong_IDs <- c('A1', 'B3', 'B7', 'Z31')
df$var1[df$var2 == 'A1' | df$var2 == 'B3' | df$var2 == 'B7' | df$var2 == 'Z31'] <- 0L

这看起来很基础,但我还没有找到一种简洁的写法。 感谢您的帮助

您可以使用 %in% 运算符将您的数据与 wrong_IDs 进行比较

df <- data.frame("var1" = 101:120, "var2" = c(1:20))
wrong_ids <- c(3, 5, 7)
df$var1[df$var2 %in% wrong_ids] <- 0

其中 df$var2 %in% wrong_ids 为您提供了一个 TRUE/FALSE 布尔向量,它仅对选定的行(此处为第 3、5 和 7 行)应用 "set to zero" 操作.

这是一个使用 grepl 和正则表达式的非常紧凑的解决方案:

一些说明性数据:

set.seed(123)
df <- data.frame(
  ID = paste0(rep(LETTERS[1:3], 2), sample(1:3, 6, replace = T)),
  Var2 = rnorm(6),
  stringsAsFactors = F)
df

wrong_IDs <- c('A1', 'B3', 'B1', 'C3')

要将包含 wrong_IDs 的那些行设置为 0,您可以将这些值折叠成仅由正则表达式交替运算符 | 分隔的单个字符串,并指示 grepl 匹配这些值df$ID 中的替代模式:

df$ID <- ifelse(grepl(paste0(wrong_IDs, collapse = "|"), df$ID), 0, df$ID)
df
  ID        Var2
1  0  0.07050839
2  0  0.12928774
3 C2  1.71506499
4 A3  0.46091621
5  0 -1.26506123
6 C1 -0.68685285