[R] Cannot be coerced to logical?

Tova Fuller suprtova at ucla.edu
Mon Oct 30 05:39:19 CET 2006


Thank you so much Mark.  That was extremely helpful.  Problem solved!

Tova

On Oct 29, 2006, at 7:47 PM, Marc Schwartz wrote:

> 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
>
>



More information about the R-help mailing list