在 r 中使用 grepl 将值替换为子字符串

Replace values using grepl in r with substrings

关注data.table

df <- data.table(id=c(1,2,3,4,5),
                 variable=c("250.00","250.13","250.56","250.01","Value1"))
1:  1   250.00
2:  2   250.13
3:  3   250.56
4:  4   250.01
5:  5   Value1

我想用 Value1 替换每个以奇数结尾的 250. 数字,用 Value2 替换其他以偶数结尾的数字。 我尝试按以下方式使用 grepl 函数。

df$variable[grepl('250\.[0-9]1|3|5', df$variable)] <-'Value1'
df$variable[grepl('250\.[0-9]0|2|4', df$variable)] <-'Value2'

但是它将所有的250.替换为Value1。 如何获得这些结果的最佳方式:

1:  1   Value2
2:  2   Value1
3:  3   Value2
4:  4   Value1
5:  5   Value1

原来的data.table有更多的值。 base 的解决方案可以处理 data.table 会很棒。

原因是您的正则表达式。这是一款真正有助于理解您的正则表达式将匹配的内容的应用程序。 https://spannbaueradam.shinyapps.io/r_regex_tester/

250\.[0-9]1|3|5 正在搜索 250\.[0-9]1 OR 3 OR 5,因为所有 250.x 都包含 5,所以它们都是匹配项。

250\.[0-9][135] 将查找以 1、3 或 5*** 结尾的值。 [] 中的值被视为 OR 列表。

*** 这不是 100% 正确,该模式将是 [135]$,但它会匹配 'Value1',因为它以 1.

结尾

使用 stringr 库的另一种方法

library(dplyr)
library(stringr)
df %>% 
  mutate(variable = str_replace_all(variable, c("250.\d?[13579]$" = "Value1", "250.\d?[02468]$" = "Value2")))
#     id variable
# 1:  1   Value2
# 2:  2   Value1
# 3:  3   Value2
# 4:  4   Value1
# 5:  5   Value1

我们也可以使用

library(data.table)
df[grepl('^[0-9]', variable),  variable := 
     c("Value2", "Value1")[(as.integer(sub(".*\.", "", variable)) %% 2)+1]]
df
#   id variable
#1:  1   Value2
#2:  2   Value1
#3:  3   Value2
#4:  4   Value1
#5:  5   Value1