My df looks like this:
N = 1000
a <- rnorm(N)
b <- rnorm(N)
c <- rnorm(N)
df <- data.frame(a, b, c)
For each of these variables, I would like to perform the following function:
ifelse(df$`i` < 10, paste0("0", df$`i`), paste0(df$`i`))
where i
is a
, b
and c
.
Is there a way I can do this in a for-loop? Thanks :)
CodePudding user response:
Do you have to use a loop?
dplyr
's across
lets you iterate a function over many columns:
library(dplyr)
df |> mutate(across(everything(),
~ifelse(.x < 10,
paste0("0", .x),
.x)))
CodePudding user response:
apply(df, 2, \(i) ifelse(i < 10, paste0("0", i), i))
Or for this case, more simply:
apply(df, 2, formatC, width = 2, flag = "0")
CodePudding user response:
If you're hoping to keep them in the frame, then the use of apply
comes with a little risk: if there are any character
columns existing in it, then when apply
converts to a matrix
before processing, you will have lost the number-ness of your other columns. (I don't know if your intended use is any more complicated than your sample data.)
Ways to mitigate this:
Use
apply
only on specific columns:df[,1:3] <- apply(df[,1:3], 2, sprintf, fmt="f")
Use
lapply
:df[1:3] <- lapply(df[1:3], sprintf, fmt="f")
Or of you're operating on the whole frame,
df[] <- lapply(df, sprintf, fmt="f")
The
df[] <-
is necessary becauselapply
returns alist
, losing thedata.frame
class. By doingdf[] <-
instead, you're reassigning the contents without changing the class, so it retains itsdata.frame
class.