Hi, I had a weird results from using apply(). Here is an simple example:> y<-data.frame(list(a=c(1,NA),b=c('2k','0'))) > y??? a???? b 1? 1?? 2k 2 NA?? 0> apply(y,1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else 0} )This should print "1 0" as output, as demonstrated by:> apply(y[1,],1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else 0} )1 1> apply(y[2,],1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else 0} )2 0 But it actually prints:> apply(y,1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else 0} )[1] 0 0 Anyone has any suggestion? Thanks John
On Aug 29, 2011, at 8:02 PM, array chip wrote:> Hi, I had a weird results from using apply(). Here is an simple > example: > >> y<-data.frame(list(a=c(1,NA),b=c('2k','0'))) >> y > > a b > 1 1 2k > 2 NA 0 > >> apply(y,1,function(x){x<-unlist(x);That is quite unnecessary since apply coerces the rows into vectors whether you want it to or not,>> if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else 0} )So everything get coerced to character and I suspect NA -> "NA" or NA_character and so !is.na() gives the wrong result. Try printing str(x) inside that apply loop. -- David.> > This should print "1 0" as output, as demonstrated by: > >> apply(y[1,],1,function(x){x<-unlist(x); if (!is.na(x[2]) & >> x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else 0} ) > 1 > 1 >> apply(y[2,],1,function(x){x<-unlist(x); if (!is.na(x[2]) & >> x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else 0} ) > 2 > 0 > > > But it actually prints: > >> apply(y,1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' >> & !is.na(x[1]) & x[1]=='1') 1 else 0} ) > > [1] 0 0 > > > Anyone has any suggestion? > > Thanks > > John > > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.David Winsemius, MD West Hartford, CT
apply() should come with a big warning that it was written for matrices and can cause a lot of surprises with data.frames. apply(X, ...) converts X to a matrix and that is the kernel of your problem: if any columns of X are not numeric then as.matrix(X) is a character matrix whose columns are made with calls to format(), which means that all entries in the column have the same number of characters in them. This is handy for printing but not for other purposes. > as.matrix(y) a b [1,] " 1" "2k" [2,] NA "0" > as.matrix(y[1,]) a b 1 "1" "2k" > as.matrix(y[2,]) a b 2 NA "0" Another way to debug this on your own is to simplify the function you are giving to apply. Then you would see where things are going wrong (but perhaps not why): > apply(y, 1, function(x)unlist(x)) [,1] [,2] a " 1" NA b "2k" "0" > apply(y[1,], 1, function(x)unlist(x)) 1 a "1" b "2k" > apply(y[2,], 1, function(x)unlist(x)) 2 a NA b "0" Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of array chip > Sent: Monday, August 29, 2011 5:03 PM > To: r-help at r-project.org > Subject: [R] weird apply() behavior > > Hi, I had a weird results from using apply(). Here is an simple example: > > > y<-data.frame(list(a=c(1,NA),b=c('2k','0'))) > > y > > ??? a???? b > 1? 1?? 2k > 2 NA?? 0 > > > apply(y,1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else > 0} ) > > This should print "1 0" as output, as demonstrated by: > > > apply(y[1,],1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 > else 0} ) > 1 > 1 > > apply(y[2,],1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 > else 0} ) > 2 > 0 > > > But it actually prints: > > > apply(y,1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]=='1') 1 else > 0} ) > > [1] 0 0 > > > Anyone has any suggestion? > > Thanks > > John > > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
"array chip":>Hi, I had a weird results from using apply().Consider: y<-data.frame(list(a=c(1,NA), b=c('2k','0'))) do.call(args=y, Vectorize(v=c("a","b"), function(a,b) if(is.na(z<-b=="2k" & a==1)) 0 else z+0)) Heikki Kaskelma Munkkiniemi
#Do apply(y,1,print) #Note the space that is inserted before the "1." If you insert this space in your function apply(y,1,function(x){x<-unlist(x); if (!is.na(x[2]) & x[2]=='2k' & !is.na(x[1]) & x[1]==' 1') 1 else 0} ) #you get the result you expect. #Also, note that your !is.na conditions are redundant for the given example because if the other conditions are true, the !is.na conditions default to true, as well. apply(y,1,function(x){x<-unlist(x); if (x[2]=='2k' & x[1]==' 1') 1 else 0} ) HTH, Daniel -- View this message in context: http://r.789695.n4.nabble.com/weird-apply-behavior-tp3777699p3778318.html Sent from the R help mailing list archive at Nabble.com.