Loop to rename variables using numbers

168 views Asked by At

I have variables named xa_1, xa_2, ..., xa_n that I want to change in certain ways.

  1. I want to create new variables named xa_n_ that I will perform these changes on
  2. Then I want to recode the values of these (categorical) variables, e.g. reversing a Likert scale

I have tried the following:

for(i in c(xa_1, xa_2, ..., xa_n) {
df$[i]_ <- df$[i] # I am sure I need to use paste() in some ways but I have been unable to figure it out
}

I tried this unsuccessfully:

a <- 1:n
for (i in seq_along(a)) {
df$paste(xa_,[i]_,sep="") <- df$paste(xa_,[i], sep="")
}

As you see, I have problems with basic functions and understanding of data manipulation in R. In short, I would like to manipulate a set of variables by combining two features of their name, that is their common core (xa_) and their identifying number (1, .., n).

Putting together all separate parts, what I would like to eventually figure out is a way to do the following:

for(i in c(xa_) {
for( j in 1:4) {
df$paste([i],[j]_, sep="") <- df$paste([i],[j],sep=") # Create a copy of existing variables that runs across variables and numbers
df$paste([i],[j]_, sep="") <- ifelse(df$paste([i],[j],sep=") == 1, 4, ifelse(df$paste([i],[j],sep=") == 2, 3,  ifelse(df$paste([i],[j],sep=")== 3, 2,  ifelse(df$paste([i],[j],sep=") == 4, 1, NA)))) # recode the new variables based on values in old variables
df$paste([i],[j],_, sep="") <- factor(paste([i],[j],_, sep=""), levels=c(1:4), labels=c("Something", "Something else", "Something else again", "Something else at last")) # Rename the values in the new variables and make them categorical 
}

Hopefully this makes enough sense so that you understand what I mean:)

1

There are 1 answers

2
ekoam On

How about doing it in a dplyr way like this?

library(dplyr)
df %>% 
  rename_with(
    ~paste0(., "_"), starts_with("xa")
  ) %>% 
  mutate(across(
    starts_with("xa"), 
    ~factor(., 4:1, c("Something", "Something else", "Something else again", "Something at last"))
  ))

Assume that your data frame looks like this:

> df
# A tibble: 10 x 6
       y     z ttt       xa_1  xa_2  xa_3
   <dbl> <dbl> <chr>    <int> <int> <int>
 1     1     2 a string     4     2     4
 2     1     2 a string     3    NA     1
 3     1     2 a string     4     1    NA
 4     1     2 a string     1    NA    NA
 5     1     2 a string    NA     1     3
 6     1     2 a string     3     2     2
 7     1     2 a string     2    NA     1
 8     1     2 a string    NA     4    NA
 9     1     2 a string     1     3    NA
10     1     2 a string     2     1     3

The code above gives you:

> df %>% rename_with(~paste0(., "_"), starts_with("xa")) %>% mutate(across(starts_with("xa"), ~factor(., 4:1, c("Something", "Something else", "Something else again", "Something at last"))))
# A tibble: 10 x 6
       y     z ttt      xa_1_                xa_2_                xa_3_               
   <dbl> <dbl> <chr>    <fct>                <fct>                <fct>               
 1     1     2 a string Something            Something else again Something           
 2     1     2 a string Something else       NA                   Something at last   
 3     1     2 a string Something            Something at last    NA                  
 4     1     2 a string Something at last    NA                   NA                  
 5     1     2 a string NA                   Something at last    Something else      
 6     1     2 a string Something else       Something else again Something else again
 7     1     2 a string Something else again NA                   Something at last   
 8     1     2 a string NA                   Something            NA                  
 9     1     2 a string Something at last    Something else       NA                  
10     1     2 a string Something else again Something at last    Something else   

Try the following code if you also want to keep those variables:

df %>% 
  mutate(across(
    starts_with("xa"), 
    ~., .names = "{.col}_"
  )) %>% 
  mutate(across(
    starts_with("xa") & ends_with("_"), 
    ~factor(., 4:1, c("Something", "Something else", "Something else again", "Something at last"))
  ))

Output:

# A tibble: 10 x 9
       y     z ttt       xa_1  xa_2  xa_3 xa_1_                xa_2_                xa_3_               
   <dbl> <dbl> <chr>    <int> <int> <int> <fct>                <fct>                <fct>               
 1     1     2 a string     4     2     4 Something            Something else again Something           
 2     1     2 a string     3    NA     1 Something else       NA                   Something at last   
 3     1     2 a string     4     1    NA Something            Something at last    NA                  
 4     1     2 a string     1    NA    NA Something at last    NA                   NA                  
 5     1     2 a string    NA     1     3 NA                   Something at last    Something else      
 6     1     2 a string     3     2     2 Something else       Something else again Something else again
 7     1     2 a string     2    NA     1 Something else again NA                   Something at last   
 8     1     2 a string    NA     4    NA NA                   Something            NA                  
 9     1     2 a string     1     3    NA Something at last    Something else       NA                  
10     1     2 a string     2     1     3 Something else again Something at last    Something else