user2105469
user2105469

Reputation: 1433

Applying a function with both char and num arguments along rows of a data.frame

I'm trying to apply a function to each row of a dataframe. That function uses a combination of chars and nums as arguments.

It's not an aggregation exercise, but the definition of a new field in an existing data.frame, based on a series of conditions using both char and num variables. All variables are in the data.frame.

I know that the apply function turns the dataframe row into a vector, in this case a char vector: I'd like to avoid re-casting the dataframe variables within the function.

There are several postings on how to use apply and the plyr package to run functions across data.frame rows but -from my novice standpoint- the examples do not mix char and num parameters on a row by row basis. Thanks.

condsIdx <- function(IDa,IDb,clss){
  if (clss == 'a'){
    y = IDa
  } else if (clss == 'b' && IDb > 14) {
    y = IDb
  } else {
    y = -1
  }
  y
}

df <- data.frame( IDa=c(1,2,3,4,5,6),
                  IDb=c(11,12,13,14,15,16),
                  clss=c('a','a','a','b','b','c'))


df$res <- -1
for ( i in 1:nrow(df) ){
  df$res[i] <- condsIdx(df$IDa[i],df$IDb[i],df$clss[i])
}

Upvotes: 0

Views: 80

Answers (2)

agstudy
agstudy

Reputation: 121608

You can use ifelse here to get a vectorized solution:

transform(df, res =  ifelse (clss == 'a', 
                             IDa,
                             ifelse(clss == 'b' & IDb > 14,IDb,  -1)))


  IDa IDb clss res
1   1  11    a   1
2   2  12    a   2
3   3  13    a   3
4   4  14    b  -1
5   5  15    b  15
6   6  16    c  -1

EDIT a typo error && not vectorized so I replace it by &.( thanks @joran)

Upvotes: 3

joran
joran

Reputation: 173677

Just use mapply or the plyr equivalent mlply:

mapply(condsIdx,IDa = df$IDa,IDb = df$IDb,clss = df$clss)
[1]  1  2  3 -1 15 -1

Upvotes: 3

Related Questions