#r #string #data.table #grepl
#r #строка #данные.таблица #grepl
Вопрос:
Следующее 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
Я хочу заменить каждое из 250.
чисел, которые заканчиваются нечетным числом, на Value1
, а остальные, которые заканчиваются четным числом, на 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
, было бы отличным.
Ответ №1:
Причиной этого является ваше регулярное выражение. Это приложение, которое действительно помогает понять, чему будет соответствовать ваше регулярное выражение. https://spannbaueradam.shinyapps.io/r_regex_tester/
250\.[0-9]1|3|5
выполняется поиск 250\.[0-9]1
ИЛИ 3
ИЛИ 5
, и поскольку все 250.x содержат 5, все они совпадают.
250\.[0-9][135]
будет выглядеть значение, которое заканчивается на 1, 3 или 5 ***. Значения в []
считаются списком ИЛИ.
*** это не на 100% правильно, такой шаблон был бы [135]$
, но это соответствовало бы ‘Value1’, потому что оно заканчивается на 1.
Ответ №2:
Другой способ, который вы можете сделать, используя 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
Ответ №3:
Мы могли бы также использовать
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