问题描述
跟随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
参数的那些值。