Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nested ifelse in R so close to working

I'm working with the following four columns of raw weight measurement data and a very nearly-functioning nested ifelse statement that results in the 'kg' vector.

     Id       G4_R_2_4         G4_R_2_5        G4_R_2_5_option2          kg
219 13237       16.0             NA                  NA                16.0
220 139129      8.50             55.70               47.20             8.50
221 139215      28.9             NA                  NA                28.9
222 139216       NA              46.70               8.50              46.70
223 139264      12.40            NA                  NA                12.40
224 139281      13.60            NA                  NA                13.60
225 139366      16.10            NA                  NA                16.10
226 139376      61.80            NA                  NA                61.80
227 140103      NA               48.60               9.10              48.60

The goal is to merge the three 'G4' columns into kg based on the following conditions: 1) If G4_R_2_4 is not NA, print its value 2) If G4_R_2_4 is NA, print the lesser of the values appearing in G4_R_2_5 and G4_R_2_5_option2 (sorry for lame variable names)

I've been working with the following statement (big dataset called 'child'):

> child$kg <- ifelse(child$G4_R_2_4 == 'NA' & child$G4_R_2_5 < child$G4_R_2_5_option2,
   child$G4_R_2_5, ifelse(child$G4_R_2_4 == 'NA' & child$G4_R_2_5 > child$G4_R_2_5_option2,
                          child$G4_R_2_5_option2, child$G4_R_2_4))

Which results in the 'kg' vector I have now. It seems to satisfy the G4_R_2_4 condition (is/is not NA) but always prints the value from G4_R_2_5 for the NA cases. How do I get it to incorporate the greater than/less than condition?

like image 369
jlev514 Avatar asked Dec 04 '25 09:12

jlev514


2 Answers

It's not clear from your example, but I think the problem is you're handling NA's incorrectly and\or using wrong type for data.frame's columns. Try rewriting your code like that:

#if your columns are of character type (warnings are ok)
child$G4_R_2_4<-as.numeric(child$G4_R_2_4)
child$G4_R_2_5<-as.numeric(child$G4_R_2_5)
child$G4_R_2_5_option2<-as.numeric(child$G4_R_2_5_option2)
#correct NA handling
child$kg<-ifelse(is.na(child$G4_R_2_4) & child$G4_R_2_5 <
   child$G4_R_2_5_option2, child$G4_R_2_5, ifelse(is.na(child$G4_R_2_4) &
     child$G4_R_2_5 > child$G4_R_2_5_option2, child$G4_R_2_5_option2, child$G4_R_2_4))
like image 143
cyberj0g Avatar answered Dec 06 '25 00:12

cyberj0g


Here is an alternative version that might be interesting, assuming that the values are stored in numerical form (else the column entries should be converted into numerical values, as suggested in the other answers):

get_kg <- function(x){
 if(!is.na(x[2])) return (x[2])
 return (min(x[3], x[4], na.rm = T))}

child$kg <- apply(child,1,get_kg)

#> child
#        Id G4_R_2_4 G4_R_2_5 G4_R_2_5_option2   kg
#219  13237     16.0       NA               NA 16.0
#220 139129      8.5     55.7             47.2  8.5
#221 139215     28.9       NA               NA 28.9
#222 139216       NA     46.7              8.5  8.5
#223 139264     12.4       NA               NA 12.4
#224 139281     13.6       NA               NA 13.6
#225 139366     16.1       NA               NA 16.1
#226 139376     61.8       NA               NA 61.8
#227 140103       NA     48.6              9.1  9.1
like image 25
RHertel Avatar answered Dec 05 '25 23:12

RHertel