Reputation: 73
I have a data frame named Cat. I have multiple columns. In one vector named Jan.15_Transaction I have values. I want to apply a condition that if value is greater than 0 then 1 else 0. So I do not want to use if else condition as there are 42 columns similar to this in which I want to apply the same the same logic.
Jan.15_Transaction Feb.15_Transaction
1 1
2 2
3 3
4 4
Hence I build this function
myfunc <- function(x){
if(x > 0){
x=1
}
else {
x=0
}
return(x)
}
This is getting applied to first element only when I use this code.
Cat$Jan.15_Transaction.1<-myfunc(Cat$Jan.15_Transaction)
Warning message: In if (x > 0) { : the condition has length > 1 and only the first element will be used
So I tried sapply and got this error below
sapply(Cat$Jan.15_Transaction.1, myfunction(Cat))
Error in match.fun(FUN) : argument "FUN" is missing, with no default
Upvotes: 1
Views: 414
Reputation: 11
I am assuming you want to apply the function on columns which have names ending with '_Transaction'. This can be done with the base function grepl
.
vars <- grepl('_Transaction', names(df))
df[, vars] <- ifelse(df[, vars] > 0, 1, 0)
You could also use dplyr
like shown below. This would generalize to more complicated functions too.
binarizer <- function(x) ifelse(x > 0, 1, 0)
df <- bind_cols(
df %>% select(-ends_with('_Transaction')),
df %>% select(ends_with('_Transaction')) %>%
mutate_each(funs(binarizer))
)
Upvotes: 1
Reputation: 545508
You can use the ifelse
function to vectorise (= apply across a vector) an if
statement:
myfunc = function (x)
ifelse(x > 0, 1, 0)
Alternatively, you could use the following which is more efficient (but less readable):
myfunc = function (x)
as.integer(x > 0)
Coming back to your original function, your way of writing it is very un-R-like. A more R-like implementation would look like this:
myfunc = function (x)
if (x > 0) 1 else 0
— No need for a temporary variable, assignments, or the return
statement.
Upvotes: 2