OHeinzen
OHeinzen

Reputation: 17

Recode and codense variables

I'm working on the output off an online questionnaire and have some trouble handling the data. This is the setups: 200 images have been rated on two 9-point-scales, totaling in 400 combinations. Unfortunately, the data hasn't been in encoded in 400 variables with values ranging from 1 to 9, but for each scale-image combination, 9 binary variables have been encoded, looking like this for two image-scale combinations:

Part. V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18
1     0  0  1  0  0  0  0  0  0  0   1   0   0   0   0   0   0   0
2     0  0  0  0  0  0  1  0  0
3                                0   0   1   0   0   0   0   0   0

As you can see, there are also some N/A values in the data set. That's because of all 400 combinations, each participant only rated a randomised 50. Given the 400 combinations, we have a total of 3600 variables in the data set. I would now like to condense and recode those values in a sense, that R counts the vars in intervals of 9, then recodes the binary 1 for a value of 1 to 9, depending on its position on the scale, and then condenses everything into 400 combination variables. In the end, it should look something like this:

Part. C1 C2
1     3  2 
2     7 
3        3

I've looked into the reshape package, but couldn't exactly figure out the way to do this.

Any suggestions?

Upvotes: 1

Views: 77

Answers (2)

zx8754
zx8754

Reputation: 56149

Using apply family functions:

#dummy data
df <- read.table(text = "
Part.,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18
1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
2,0,0,0,0,0,0,1,0,0,,,,,,,,,
3,,,,,,,,,,0,0,1,0,0,0,0,0,0
", header = TRUE, sep = ",")

# result

# cbind - column bind, put columns side by side
cbind(
  # First column is the "Part." column
  df[, "Part.", drop = FALSE],
  # other columns are coming from below code
  # sapply returns matrix, converting it to data.frame so we can use cbind.
      as.data.frame(
        # get data column index 9 columns each, first 2 to 9, then 10 to 18, etc.
        sapply(seq(2, ncol(df), 9), function(i)
          # for each 9 columns check at which position it is equal to 1,
          # using which() function
          apply(df[, i:(i + 8)], 1, function(j) which(j == 1)))
      )
)

#output
#   Part. V1 V2
# 1     1  3  2
# 2     2  7   
# 3     3     3

Upvotes: 1

Alex
Alex

Reputation: 4995

Here is a solution for a small example. I did it for only 2 possible outcomes. So v1 = 1 for pic 1, v2 = 2 for pic one, v3 = 1 for pic 2 ... . If you have 9 possible outcomes you have to change id <- rep(1:2, each = 2) to id <- rep(1:n, each = 9) where n is the total number of pictures. Also change the 2 in final <- matrix(nrow = nrow(dat), ncol = ncol(dat)/2) to 9.

I hope that helps.

dat <- data.frame(v1 = c(NA,0,1,0), v2 = c(NA,1,0,1), v3 = c(0,1,NA,0), v4 = c(1,0,NA,1))
id <- rep(1:2, each = 2)           
final <- matrix(nrow = nrow(dat), ncol = ncol(dat)/2)

for (i in unique(id)){
  wdat  <- dat[ ,which(id == i)]
   for (j in 1:nrow(wdat)){
     if(is.na(wdat[j,1] )) { 
        final[j,i] <- NA 
     } else {
       final[j,i] <- which(wdat[j, ] == 1)
     }

   }  
}

The input and output for my example:

> dat
  v1 v2 v3 v4
1 NA NA  0  1
2  0  1  1  0
3  1  0 NA NA
4  0  1  0  1

> final
     [,1] [,2]
[1,]   NA    2
[2,]    2    1
[3,]    1   NA
[4,]    2    2

Upvotes: 0

Related Questions