2
votes

I have the following character vector of numeric values.

X0 <- c("288", "74.00 [67.75, 80.00]", "196 (68.1)", "64.50 [57.00, 72.00]", 
"1.90 [1.80, 2.00]", "27.65 [25.37, 30.63]", "138.00 [125.00, 152.00]", 
"74.00 [67.50, 81.00]", "29 (10.2)", "2.84 [2.54, 3.20]", "18.00 [14.00, 23.00]", 
"1.26 [1.07, 1.47]", "0.65 [0.58, 0.75]", "2.20 [2.00, 2.36]", 
"3.80 [3.14, 4.36]", "21.80 [19.20, 25.00]", "43.89 [37.56, 50.00]", 
"65.00 [60.00, 65.00]", "274 (95.1)", "253 (87.8)", "", "59 (20.5)", 
"189 (65.6)", "40 (13.9)", "", "8 (21.6)", "6 (16.2)", "21 (56.8)", 
"2 ( 5.4)", "851.50 [492.00, 1426.00]", "601.50 [337.75, 947.75]", 
"447.50 [261.25, 740.50]", "226.50 [130.00, 353.25]", "43 (14.9)", 
"4.50 [0.00, 30.25]", "11 ( 8.9)", "39 (31.7)", "3.38 [1.90, 5.22]"

I need to replace all decimal numbers with rounded values to 1 decimal places.

I tried the this:

str_replace(X0, "[0-9]{1,}(\\.)[0-9]{1,}", as.character(round(as.numeric("\\0"),1)))

and a couple of other variations of the following, but it only produces results with NA.

How can I replace these values as characters? This is unfortunately how the data comes to me. I need to replace these values in place. I can't simply convert each element to numeric since there are these parenthesis and brackets that I can't remove.

2
In R, Arrays start with element 1, not element 0. So I think that your re[placement should be "\\1" Not "\\0".G5W
Where did this string come from in the first place? Seems like it would be easier to fix the data when you make the string rather than after the fact.MrFlick
I agree, but the data that came from is from another source and team who's using a package (which I can't recall) and the data is presented the way it is. Now, generally this is also okay to show with 2 dec places, but in my case I need one decimal places for a journal style. This is one time thing, and it'd be too much to ask other team to change for this purpose only, although would be appropriate. But we all know, that's not gonna happen immediately.user1828605
@G5W, when I used \\1, all i received was a decimal (period). But when I used \\0, it didn't do anything, could be because of the things you pointed out. When I pasted the code, that was the last thing I had tried so I didn't realize it had been copied like thatuser1828605

2 Answers

2
votes

Try using str_replace_all with a callback function:

library(stringr)
str_replace_all(X0, "\\b\\d+\\.\\d+\\b", function(x) as.character(round(as.numeric(x), 1)))

The idea here is to match and replace any decimal number with its rounded to one decimal place version. Note that in the callback function we need to cast twice, once to numeric to do the round, and then a second time to get back a character version of the rounded number.

As Mr. Flick has pointed out already, it might be easier to just fix your data at its source rather than going this route.

0
votes

An attempt using strsplit().

parentheses <- grep("\\(", X0)
brackets <- grep("\\[", X0)

values <- lapply(strsplit(X0, "\\,|\\[|\\]|\\(|\\)"), function(x) round(as.numeric(x), 1))

values[parentheses] <- Map(function(x) paste0(x[1], " (", x[2], ")"), values[parentheses])
values[brackets] <- Map(function(x) paste0(x[1], " [", x[2], ", ", x[3], "]"), values[brackets])
unlist(values)
# [1] "288"                  "74 [67.8, 80]"        "196 (68.1)"           "64.5 [57, 72]"       
# [5] "1.9 [1.8, 2]"         "27.6 [25.4, 30.6]"    "138 [125, 152]"       "74 [67.5, 81]"       
# [9] "29 (10.2)"            "2.8 [2.5, 3.2]"       "18 [14, 23]"          "1.3 [1.1, 1.5]"      
# [13] "0.6 [0.6, 0.8]"       "2.2 [2, 2.4]"         "3.8 [3.1, 4.4]"       "21.8 [19.2, 25]"     
# [17] "43.9 [37.6, 50]"      "65 [60, 65]"          "274 (95.1)"           "253 (87.8)"          
# [21] "59 (20.5)"            "189 (65.6)"           "40 (13.9)"            "8 (21.6)"            
# [25] "6 (16.2)"             "21 (56.8)"            "2 (5.4)"              "851.5 [492, 1426]"   
# [29] "601.5 [337.8, 947.8]" "447.5 [261.2, 740.5]" "226.5 [130, 353.2]"   "43 (14.9)"           
# [33] "4.5 [0, 30.2]"        "11 (8.9)"             "39 (31.7)"            "3.4 [1.9, 5.2]"