Reputation: 1898
What I would like to to
I would like to round all numeric values of a large data set depending on their actual decimal place.
E.g. for the df
below, I would like to round all numbers, numbers with one decimal place to a full number and numbers with two decimal places to one decimal place.
Update
In the original post, I used iris
as data set. Since iris
does only have 1 decimal place, I added a new data set:
df <- tibble(one=round(runif(100,0,10), 1),
two=round(runif(100,0,10), 2),
characters=rep("thanks",100))
Upvotes: 1
Views: 388
Reputation: 21400
DATA:
v1 <- c(1.1, 1.2, 2.91, 5.9)
SOLUTION for vector:
Key here is the identification of numbers with 2 decimals via regular expression using grepl
; to make the regex work, the data need to be converted to character using as.character
. Then you can simply set up an ifelse
clause determining that if the condition evaluates to TRUE, round
to 1 decimal, else round to 0 decimals:
ifelse(grepl(".\\d{2}$", as.character(v1)), round(v1,1), round(v1,0))
RESULT:
[1] 1.0 1.0 2.9 6.0
SOLUTION for dataframe:
The same principle can be applied to transforming several vectors in a dataframe in one go:
dt <- data.frame(
v1 = c(1.11, 2.2, 3.9, 5.55),
v2 = c(6.99, 7.07, 8.5, 9.01))
The above sketched out solution just needs to be made part of a function inside an apply
statement:
apply(dt, 2, function(x) ifelse(grepl(".\\d{2}$", as.character(x)), round(x,1), round(x,0)))
v1 v2
[1,] 1.1 7.0
[2,] 2.0 7.1
[3,] 4.0 8.0
[4,] 5.5 9.0
Upvotes: 1
Reputation: 51592
You can just count the digits after the dot and round to that value-1, i.e.
x <- c(4.5, 2.12, 3, 5.245)
i1 <- nchar(sub('.*\\.', '', x))
round(x, (i1-1))
#[1] 4.00 2.10 3.00 5.25
Upvotes: 5