Ty Voss
Ty Voss

Reputation: 283

Adding two decimal places

I have a column in a dataset as shown below

            Col1
            ----------
            249
            250.8
            251.3
            250.33
            648
            1249Y4
            X569X3
            4459120  
            2502420

What I am trying to do is add two decimal places only to number that have only three digits , in other words, numbers that are in hundreds. For example, 249 should be converted to 249.00, 251.3 should be converted to 251.30 so on and not 4459120 or 2502420 or X569X3. The final output should look like this.

           Col1
            ----------
            249.00
            250.80
            251.30
            250.33
            648.00
            1249Y4
            X569X3
            4459120  
            2502420

I have looked at many different functions so far none of those work because there are some strings in between the numbers, for example X569X3 and seven digit numbers 2502420


Actual dataset

structure(c(5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 
16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 
29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 
42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 52L, 53L, 54L, 
55L, 56L, 57L, 58L, 59L, 84L, 86L, 87L, 88L, 99L, 100L, 101L, 
102L, 103L, 104L, 105L, 106L, 107L, 108L, 110L, 5L, 12L, 14L, 
16L, 20L, 24L, 36L, 40L, 44L, 48L, 52L, 56L, 83L, 85L, 75L, 112L, 
66L, 68L, 96L, 93L, 77L, 80L, 81L, 70L, 95L, 78L, 109L, 94L, 
63L, 67L, 98L, 73L, 79L, 76L, 90L, 111L, 69L, 97L, 64L, 92L, 
89L, 82L, 62L, 74L, 60L, 65L, 71L, 91L, 61L, 72L, 4L, 1L, 2L, 
3L, 113L), .Label = c("1234X1", "123871", "1249Y4", "146724", 
"249", "249.01", "249.1", "249.11", "249.2", "249.21", "249.3", 
"249.4", "249.41", "249.5", "249.51", "249.6", "249.61", "249.7", 
"249.71", "249.8", "249.81", "249.9", "249.91", "250", "250.01", 
"250.02", "250.03", "250.1", "250.11", "250.12", "250.13", "250.22", 
"250.23", "250.32", "250.33", "250.4", "250.41", "250.42", "250.43", 
"250.5", "250.51", "250.52", "250.53", "250.6", "250.61", "250.62", 
"250.63", "250.7", "250.71", "250.72", "250.73", "250.8", "250.81", 
"250.82", "250.83", "250.9", "250.91", "250.92", "250.93", "2502110", 
"2502111", "2502112", "2502113", "2502114", "2502115", "2502210", 
"2502310", "2502410", "2502420", "2502510", "2502610", "2502611", 
"2502612", "2502613", "2502614", "2502615", "2506110", "2506120", 
"2506130", "2506140", "2506150", "2506160", "251.3", "251.8", 
"253.5", "258.1", "275.01", "277.39", "3640140", "3670110", "3670150", 
"3748210", "3774410", "3774420", "4459120", "5379670", "5379671", 
"6221340", "648", "648.01", "648.02", "648.03", "648.04", "648.8", 
"648.81", "648.82", "648.83", "648.84", "7079180", "775.1", "7821120", 
"7862120", "X569X3"), class = "factor")

Upvotes: 0

Views: 98

Answers (3)

Steven Beaupré
Steven Beaupré

Reputation: 21641

First, change your dataset to character:

x <- as.character(x)

Then perform the following:

ifelse(grepl("[[:alpha:]]", x) == FALSE & as.numeric(x) < 1000, 
                          sprintf("%.2f", as.numeric(x)), x)

Or if your data is in Col1 in a dataframe:

df %>% 
  mutate(Col1 = ifelse(grepl("[[:alpha:]]", Col1) == FALSE & as.numeric(as.character(Col1)) < 1000, 
                            sprintf("%.2f", as.numeric(as.character(Col1))), as.character(Col1)))

Upvotes: 1

thelatemail
thelatemail

Reputation: 93938

Use formatC with a selection of only the values you wish to replace.

x <- c("249", "250.8", "251.3", "250.33", "648", "1249Y4", "X569X3", "4459120", "2502420")
sel <- which(as.numeric(x) < 1000)
replace(x, sel, formatC(as.numeric(x[sel]), digits=2, format="f"))
#[1] "249.00"  "250.80"  "251.30"  "250.33"  "648.00"  "1249Y4"  "X569X3" 
#[8] "4459120" "2502420"

Upvotes: 3

Gregor Thomas
Gregor Thomas

Reputation: 146249

Let's call your vector x:

numbers = !is.na(as.numeric(x))
x.num = x[numbers]

x[numbers] = ifelse(as.numeric(x.num) < 1000,
       sprintf("%.2f", as.numeric(x.num)),
               x.num)
x

# [1] "249.00"  "250.80"  "251.30"  "250.33"  "648.00"
# [6] "1249Y4"  "X569X3"  "4459120" "2502420"

Upvotes: 4

Related Questions