On Sun, 2006-10-29 at 18:34 -0800, Tova Fuller wrote:> Hello all,
>
> So I am having a puzzling problem. I am working with a 534 x 1065
> data frame entitled LocalMaxExpBlue.COR which is completely full of
> logical values "TRUE" and "FALSE." However, when I
attempt to
> manipulate this data frame, R does not recognize it as logical.
> Strangely enough, it will identify individual columns (but not rows)
> as logical. It will also identify all of the individual elements of
> each row as logical. Here are some examples:
>
> > is.logical(LocalMaxExpBlue.COR)
> [1] FALSE
>
> > is.logical(LocalMaxExpBlue.COR[,1])
> [1] TRUE
>
> > is.logical(LocalMaxExpBlue.COR[1,])
> [1] FALSE
>
> # If we look at the first five values of the first row, we notice
> that each value is indeed logical:
> > LocalMaxExpBlue.COR[1,c(1:5)]
> X1 X2 X3 X4 X5
> 1 FALSE FALSE FALSE FALSE FALSE
>
> # However, it does not recognize this!:
> > is.logical(LocalMaxExpBlue.COR[1,c(1:5)])
> [1] FALSE
>
> # It does recognize that individual values of each row are logical:
> > is.logical(LocalMaxExpBlue.COR[1,1])
> [1] TRUE
> > is.logical(LocalMaxExpBlue.COR[1,2])
> [1] TRUE
> # etc.
>
> Thank you in advance for your help. Perhaps I have made some small
> obvious mistake.
is.logical() is a generic method and knows nothing about logical data
frames. So in any of your subsetting where you are including multiple
columns, it is going to return FALSE. Keep in mind that data frames are
a list. As long as you are passing is.logical() vectors (ie. individual
columns or parts of individual columns), you are OK.
Depending upon what you are doing with the data, the easiest thing is
just to convert the data frame to a logical matrix.
For example, I created a data frame with all logical columns, similar to
yours:
> str(DF)
'data.frame': 534 obs. of 1065 variables:
$ V1 : logi TRUE FALSE TRUE FALSE TRUE FALSE TRUE TRUE TRUE TRUE
TRUE FALSE ...
$ V2 : logi TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE
TRUE FALSE ...
$ V3 : logi TRUE FALSE FALSE TRUE FALSE TRUE FALSE TRUE FALSE FALSE
TRUE FALSE ...
$ V4 : logi TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE
TRUE FALSE ...
$ V5 : logi TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE TRUE TRUE
FALSE FALSE ...
$ V6 : logi FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE TRUE
FALSE FALSE ...
$ V7 : logi TRUE FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE
FALSE TRUE ...
$ V8 : logi TRUE TRUE FALSE TRUE TRUE FALSE TRUE FALSE FALSE FALSE
TRUE TRUE ...
$ V9 : logi TRUE TRUE FALSE TRUE FALSE TRUE TRUE TRUE TRUE FALSE
FALSE TRUE ...
$ V10 : logi TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE
TRUE FALSE ...
> is.logical(DF)
[1] FALSE
> is.list(DF)
[1] TRUE
> mat <- as.matrix(DF)
> str(mat)
logi [1:534, 1:1065] TRUE FALSE TRUE FALSE TRUE FALSE TRUE TRUE
TRUE TRUE TRUE FALSE ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:534] "1" "2" "3" "4" ...
..$ : chr [1:1065] "V1" "V2" "V3" "V4"
...
> is.logical(mat)
[1] TRUE
Since DF is a list, you can also do the following:
> all(sapply(DF, is.logical))
[1] TRUE
Since the individual columns will be passed as a vector to is.logical(),
if all() of the values come back as TRUE, then the result of the above
will be TRUE. See ?sapply and ?all for more information.
You can also extend is.logical() by creating a data frame method for it.
Again, we now start at the beginning:
> is.logical(DF)
[1] FALSE
Create a data frame method, based upon our function above:
> methods(is.logical)
no methods were found
# Create a new method
is.logical.data.frame <- function(x) {all(sapply(x, is.logical))}
> methods(is.logical)
[1] is.logical.data.frame
> is.logical(DF)
[1] TRUE
So, now is.logical() has a method for data frames and will return the
correct result.
HTH,
Marc Schwartz