1

I have a dataframe for a likert scale questionnarie. All of the questions have a 1-10 scale, but to run some analyses I want to recode the scale to be from 1 to 5.

So, I want to recode most of the variables of my data frame, excluding identification variables. I've tried several things and looked also into past threads but I cannot find a solution, I always get an error.

Since I'm new to R I believe it is just a rookie mistake but I hope you can help me.

Here is the code:

z <- data.frame (ID = c(23,24,25,26,27),
              Project = c("EA","EA","PLA","PLA","PLA"),
              Q1 = c(3,9,8,5,10),
              Q2 = c(1,2,6,7,9),
              Q3 = c(4,8,6,6,10))

recode_z <- z[,3:5] 

p3[,recode_p3] <- as.data.frame(lapply(p3[, recode_p3], function(x)ifelse(x == 2, 1), 
                                                                   ifelse(x == 3, 2), 
                                                                   ifelse(x== 4, 2),
                                                                   ifelse(x== 5, 3),
                                                                   ifelse(x== 6, 3),
                                                                   ifelse(x== 7, 4),
                                                                   ifelse(x== 8, 4),
                                                                   ifelse(x== 9, 5),
                                                                   ifelse(x== 10, 5,x)))

I get this error:

Error in .subset(x, j) : invalid subscript type 'list'

Can you spot the mistake? Thank you in advance!

zx8754
  • 52,746
  • 12
  • 114
  • 209
Gigi39
  • 45
  • 3

2 Answers2

4

ifelse needs yes as well as no condition. So you could change your code to :

z[, 3:5] <- lapply(z[, 3:5], function(x)ifelse(x == 2, 1), 
                                       ifelse(x == 3, 2, 
                                       ifelse(x== 4, 2,
                                       ifelse(x== 5, 3,
                                       ifelse(x== 6, 3,
                                       ifelse(x== 7, 4,
                                       ifelse(x== 8, 4,
                                       ifelse(x== 9, 5,
                                       ifelse(x== 10, 5,x)))))))))

However, instead of writing each condition individually you can combine them into one and use %in% to check multiple values. Also use dplyr::case_when might help improve readability of the code.

z[,3:5] <- lapply(z[, 3:5], function(x) {
  dplyr::case_when(x == 2 ~ 1, 
                   x %in% 3:4 ~ 2, 
                   x %in% 5:6 ~ 3, 
                   x %in% 7:8 ~ 4, 
                   x %in% 9:10 ~ 5, 
                   TRUE ~ x)
})
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
1

Noting that the values are integers between 2 and 10 and that

(2:10) %/% 2
#[1] 1 1 2 2 3 3 4 4 5

therefore the new values are given by

(2:10 + 1) %/% 2
#[1] 1 2 2 3 3 4 4 5 5

here is a one-liner.

recode_z <- 3:5
z[recode_z] <- lapply(z[recode_z], function(x) (x + 1L) %/% 2L)

z
#  ID Project Q1 Q2 Q3
#1 23      EA  2  1  2
#2 24      EA  5  1  4
#3 25     PLA  4  3  3
#4 26     PLA  3  4  3
#5 27     PLA  5  5  5
Rui Barradas
  • 70,273
  • 8
  • 34
  • 66