简体   繁体   中英

Can I run a loop over multiple columns in R?

so I want to replace the values within my columns, by replacing "Zero" to "0", "One" to "1" and "Two" to "2". From:

V1 V2 V3
Two Two One
Zero Two One
One One One

To:

V1 V2 V3
2 2 1
0 2 1
1 1 1

However, I have many many columns that I need to do this with, so I try to write a function that can replace the values of one column (shown below), and make a for loop to repeat the same thing for multiple columns.

testfunction <- function(column){
    df <<- transform(df, column
                             = as.integer(as.character(
                                 factor(column, 
                                        levels = c("Zero", "One", "Two"),
                                        labels = c(0, 1, 2)
    ))))
}

The for loop:

a <- 1
for(i in 1:ncols(df)){
    a <- a + 1
    column <- colnames(df[a])
    testfunction(column)
}

However, this doesn't seem to work. I assume I should have done it with a nested for loop in a cell by cell basis. But is there anyway you can do it by a column by column basis?

Thank you in advanced for any help

We can use mutate with across

library(dplyr)
df %>%
  mutate(across(everything(), ~ as.integer(as.character(factor(., 
            levels = c("Zero", "One", "Two"),
                                    labels = c(0, 1, 2))))))

-output

#   V1 V2 V3
#1  2  2  1
#2  0  2  1
#3  1  1  1

Or this can be done in base R in a single line. Also, can be extended to many more levels without having to write new lines of code

df[] <- lapply(df, function(x) setNames(c(0, 1, 2), c("Zero", "One", "Two"))[x])

data

df <- structure(list(V1 = c("Two", "Zero", "One"), V2 = c("Two", "Two", 
"One"), V3 = c("One", "One", "One")), class = "data.frame", row.names = c(NA, 
-3L))

If you have only three numbers you can use indexing and finally formating as numeric values:

#Code
df[df=='Zero']<-0
df[df=='One']<-1
df[df=='Two']<-2
df <- as.data.frame(sapply(df, as.numeric))

Output:

  V1 V2 V3
1  2  2  1
2  0  2  1
3  1  1  1

A simple base R option using setNames

df[] <- setNames(0:2, c("Zero", "One", "Two"))[unlist(df)]

such that

> df
  V1 V2 V3
1  2  2  1
2  0  2  1
3  1  1  1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM