Shekar
Shekar

Reputation: 93

Applying round function to every element in a dataframe

Suppose I have a dataframe in R like this

x = c(2, 3.432, 5)
y = c(4.5345, NA, "text")
z = c(8.13451, 3.12451, 6.12341)
A = data.frame(x, y, z)

How do I apply the round function to the appropriate elements of the dataframe? Essentially I want to:

I have read in numerous places that loops are not a good idea in R. Trying lines like

A$y[is.numeric(A$y)] <- round(A$y, digits = 3)

does not work

Upvotes: 9

Views: 6296

Answers (3)

user2110417
user2110417

Reputation:

You can also try:

library(dplyr)
df %>% mutate_if(is.numeric, round)

Upvotes: 1

Arthur Yip
Arthur Yip

Reputation: 6230

You have the right idea about loops. As @jennybryan says: "of course someone has to write loops. It doesn't have to be you."

Using lapply with an ifelse as @akrun suggests is one way. Using dplyr to work on data frames is another way and is part of a "tidyverse" of packages and functions that have consistent syntax and are descriptive in their names (wordier but arguably worth it).

To do what your question asks,

x = c(2, 3.432, 5)
y = c(4.5345, NA, "text")
z = c(8.13451, 3.12451, 6.12341)
A = data.frame(x, y, z)
library(dplyr)
mutate(A, across(where(is.numeric), round, 3))
#>       x      y     z
#> 1 2.000 4.5345 8.135
#> 2 3.432   <NA> 3.125
#> 3 5.000   text 6.123

# can also be written as
# A %>% mutate(across(where(is.numeric), round, 3))

Created on 2020-10-29 by the reprex package (v0.3.0)

Upvotes: 4

akrun
akrun

Reputation: 887148

We can try with lapply

A[] <- lapply(A, function(x) if(is.numeric(x)) round(x, 3) else x)

If we need to change the format of numeric elements in those with character/factor class columns as well

A[] <- lapply(A, function(x) {
           x1 <- type.convert(as.character(x), as.is=TRUE)
    ifelse(grepl("^[0-9.]+$", x1), round(as.numeric(x1), 3), x1)})

Upvotes: 3

Related Questions