user3596790
user3596790

Reputation: 71

conditional assignment of values

I have a dataset with you variables:

              ACCURACY     Feedback
141            0             3
156            0             1
167            1             2
185            1             1
191            1             NA
193            1             1

I have created a new column called X, where I would like to assign 3 potential values (correct, incorrect, unknown) based on combinations between the previous two values (i.e. accuracy ~ Feedback).

I have tried the next:

df$X=NA     
df[!is.na((df$ACC==1)&(df$Feedback==1)),]$X <- "correct"
df[!is.na((df$ACC==1)&(df$Feedback==2)),]$X <- "unknown"
df[!is.na((df$ACC==1)&(df$Feedback==3)),]$X <- "incorrect"
df[!is.na((df$ACC==0)&(df$Feedback==1)),]$X <- "correct"
df[!is.na((df$ACC==0)&(df$Feedback==2)),]$X <- "unknown"
df[!is.na((df$ACC==0)&(df$Feedback==3)),]$X <- "incorrect"

But it doesnt assign a value in X based on both ACC and Feedback, but each line of code overrides the values assigned by the previous one. I would appreciate any guidance/suggestions.

Upvotes: 0

Views: 4820

Answers (3)

Curt
Curt

Reputation: 1414

The issue is that you've wrapped all the assignment conditions with !is.na. These vectors all evaluate to the same thing. For example:

> !is.na((df$ACC==1)&(df$Feedback==2))
[1]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
> !is.na((df$ACC==1)&(df$Feedback==3))
[1]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE

A possible solution would be to write a little function to do the assignments you want, and then use apply.

recoder <- function(row) {                                                  
    accuracy <- row[['ACCURACY']]                                           
    feedback <- row[['Feedback']]                                           

    if(is.na(accuracy) || is.na(feedback)) {                                
        ret_val <- NA                                                       
    }                                                                       
    else if((accuracy==1 && feedback==1) || (accuracy==0 && feedback==1)) { 
        ret_val <- "correct"                                                
    }                                                                       
    else if((accuracy==1 & feedback==2) || (accuracy==0 & feedback==2)) {   
        ret_val <- "unknown"                                                
    }                                                                       
    else {                                                                  
        ret_val <- "incorrect"                                              
    }                                                                       

    return(ret_val)                                                         
}                                                                           
df$X <- apply(df, 1, recoder)

df     
> df                                                                        
    ACCURACY Feedback         X                                             
141        0        3 incorrect                                             
156        0        1   correct                                             
167        1        2   unknown                                             
185        1        1   correct                                             
191        1       NA      <NA>                                             
193        1        1   correct    

Upvotes: 0

sboysel
sboysel

Reputation: 641

If the values of X indeed do not depend on ACCURACY, you could just recode Feedback as a factor

df$X <- factor(df$Feedback,
               levels = c(1, 2, 3),
               labels = c("correct", "unkown", "incorrect"))

Upvotes: 0

cpander
cpander

Reputation: 374

This can be done with nested ifelse functions. Although, based on the example posted, it looks like X depends only on Feedback, never ACCURACY.

  ACCURACY Feedback
1        0        3
2        0        1
3        1        2
4        1        1
5        1       NA
6        1        1

df$X <- ifelse(df$ACCURACY == 1, ifelse(df$Feedback == 1, "correct", ifelse(df$Feedback == 2, "unknown", "incorrect")), ifelse(df$Feedback == 1, "correct", ifelse(df$Feedback == 2, "unknown", "incorrect")))

  ACCURACY Feedback           X
1        0        3   incorrect
2        0        1     correct
3        1        2     unknown
4        1        1     correct
5        1       NA        <NA>
6        1        1     correct

Upvotes: 2

Related Questions