1

I have a multipart function to convert characters in a specified column to numbers, as follows:

ccreate <- function(df, x){ revalue(df[[x]], c( "?"=1 , "D"=2 , "C"=3 , "B"=4 , "A"=5 )) }

I then use that function to create new columns in my original dataset of just the values using another function:

coladd <- function(df, x){ df[[paste(x, "_col", sep='' )]] <- ccreate(df,x) df }

Here is an example of the function:

col1 <- c("A", "B", "C", "D", "?")
col2 <- c("A", "A", "A", "D", "?")
col3 <- c("C", "B", "?", "A", "B")
test <- data.frame(col1, col2, col3)
test
coladd(test, "col1")

This works, but I have to feed each column name from my dataset into coladd() one at a time. Is there a way to apply the coladd() function to every column in a dataframe without having to type in each column name?

Thanks again, and sorry for any confusion, this is my first post here.

jnasta214
  • 25
  • 4
  • 4
    It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Aug 04 '21 at 19:26
  • Thank you MrFlick, I will update with an example. – jnasta214 Aug 04 '21 at 19:52
  • I think you have a typo in your `coladd`. Should it be `ccreate(df,x); df` at the end? –  Aug 04 '21 at 19:57

1 Answers1

1

Using your functions, you can use Reduce.

ccreate <- function(df, x){ revalue(df[[x]], c( "?"=1 , "D"=2 , "C"=3 , "B"=4 , "A"=5 )) }

coladd <- function(df, x){ df[[paste(x, "_col", sep='' )]] <- ccreate(df,x); df }

Reduce(coladd, names(test), test)
#   col1 col2 col3 col1_col col2_col col3_col
# 1    A    A    C        5        5        3
# 2    B    A    B        4        5        4
# 3    C    A    ?        3        5        1
# 4    D    D    A        2        2        5
# 5    ?    ?    B        1        1        4

Here is how I would do it, though not using your functions.

library(dplyr)

# this is a named vector to serve as your lookup
recode_val <- c( "?"=1 , "D"=2 , "C"=3 , "B"=4 , "A"=5 )

test %>%
  mutate(across(everything(), list(col = ~ recode_val[.])))

#   col1 col2 col3 col1_col col2_col col3_col
# 1    A    A    C        5        5        3
# 2    B    A    B        4        5        4
# 3    C    A    ?        3        5        1
# 4    D    D    A        2        2        5
# 5    ?    ?    B        1        1        4