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.