Reputation: 99351
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
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