Rich Scriven
Rich Scriven

Reputation: 99351

R -- Undefined truth values in if statements

What is the "standard protocol" for running a condition that has an undefined truth value through an if statement? Namely, I'm referring to length. I am working on a function, grep.dataframe that will extract (with grep) or replace (with gsub) values in a data frame without having to write loops every time. Here's where I'm at:

> dat <- data.frame(x = letters[1:3])
> grep.dataframe('f', dat)
# character(0) 

So I decided to add an if statement so that grep.dataframe returns something a bit more widely comprehensible if there are no matches, like NULL. if(length(d) == 0) NULL else d seems nice. But that doesn't look nearly as pretty as if(is.integer(x)). Consider the fact that there are 159 as. or is. functions in the base package alone. I couldn't find one that was for this issue. So then, my question is, How do those published R developers handle this situation in their code?

I thought of doing this, which doesn't seem half bad I guess.

has.length <- function(x)
{
    if(length(x) > 0) TRUE else FALSE
}

> has.length(character(0))
# [1] FALSE
> has.length(1)
# [1] TRUE

which led to

> df1 <- data.frame(x = 1)
> if(!has.length(df1)) NULL else df1
#   x
# 1 1
> df2 <- data.frame(x = numeric())
> if(!has.length(df2)) NULL else df2
# [1] x
# <0 rows> (or 0-length row.names)

which does not work (thanks @MrFlick for correcting that). I would like to know the elegant, R developer way to do this.

Cheers.

ADD : So that people have an idea of what I'm doing, here are three results. The function is working nicely now, as agstudy's answer did the trick. Now all I have to get right are the inherits of classes.

> args(grep.dataframe)
function (pattern, X, sub = NULL, ...) 
NULL

> dat <- data.frame(x = letters[1:4], y = c('b', 'd', 'a', 'f'))
> grep.dataframe('a|f', dat)  ## returns a named list of values found by column
# $x
#   value row
# 1     a   1

# $y
#   value row
# 1     a   3
# 2     f   4

> grep.dataframe('a|f', dat, sub = 'XXX')  ## returns the gsub'ed data frame
#     x   y
# 1 XXX   b
# 2   b   d
# 3   c XXX
# 4   d XXX

> grep.dataframe('h', dat)
# NULL

Upvotes: 1

Views: 641

Answers (1)

agstudy
agstudy

Reputation: 121588

I would do something like this :

 check_x <- function(x) if(length(x)) x else NULL
 x <- character(0)
 check_x(x)
 x <- 'a'
 check_x(x)
 [1] "a"

or also simply to omit the return :

check_x <- function(x) if(length(x)) x 

Upvotes: 1

Related Questions