在R中使用正则表达式将数字替换为空白

问题描述

跟随data.table

df <- data.table(id=c(1,2,3,4),variable=c("250","250.1","250.11","E70.9"))
df
id variable
1:  1      250
2:  2    250.1
3:  3   250.11
4:  4   E70.9

我想添加到较短的字符串0中以填充小数,但前提是它必须以250开头。到目前为止,我做了以下事情:

df <- set(df,which(df[,'variable']=="250"),'variable',value= '250.00')
df$variable <- str_replace_all(df$variable,"([2][5][0]\\.[:digit:][:space:])","([2][5][0]\\.[:digit:][0]))")

第一部分正在运行,我可以将250替换为250.00。当我尝试使用stringsr软件包和regex时,它没有解决问题。最后,我想得到这些结果。

id variable
1:  1   250.00
2:  2   250.10
3:  3   250.11
4:  4   E70.9

要以正确的方式使用stringr,我应该怎么做?在data.table中也许有更好的解决方案?

解决方法

我们可以使用sprintf。通过检查“变量”是否以“ 250”开头来创建带有case_when的逻辑条件,然后使用sprintf格式化那些元素,否则返回“变量”

library(dplyr)
df %>%
    mutate(variable = case_when(str_detect(variable,'^250')
       ~ sprintf('%.2f',as.numeric(variable)),TRUE ~ variable))

或与base R

i1 <- grepl('^250',df$variable)
df$variable[i1] <- sprintf('%.2f',as.numeric(df$variable[i1]))
,

一种data.table替代方案:

func <- function(x) {
  num <- suppressWarnings(as.numeric(x))
  ifelse(is.na(num),x,sprintf("%0.2f",num))
}
df <- data.table(id=c(1,2,3,4),variable=c("250","250.1","250.11","E70.9"))
df[grepl("^250",variable),variable := func(variable) ]
#    id variable
# 1:  1   250.00
# 2:  2   250.10
# 3:  3   250.11
# 4:  4    E70.9

这可以利用sprintf很好地完成格式化数字的工作。

此方法的一个优点是,如果您的“ 250” 规则是因为您不想调整"E70.9"值,那么它就可以正常工作了(因为“ E”破坏as.numeric):

df <- data.table(id=c(1,"E70.9"))
df[,variable := func(variable) ]
#    id variable
# 1:  1   250.00
# 2:  2   250.10
# 3:  3   250.11
# 4:  4    E70.9
,

您可以通过以下方式使用str_replace

library(data.table)

df[,variable := stringr::str_replace(variable,'^250.*',function(m) 
                 sprintf('%.2f',as.numeric(m)))]
df
#   id variable
#1:  1   250.00
#2:  2   250.10
#3:  3   250.11
#4:  4    E70.9

str_replace仅替换满足pattern参数的那些值。