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
applyonly 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 becauselapplyreturns alist, losing thedata.frameclass. By doingdf[] <-instead, you're reassigning the contents without changing the class, so it retains itsdata.frameclass.
