colinfang
colinfang

Reputation: 21757

How to avoid listing out function arguments but still subset too?

I have a function myFun(a,b,c,d,e,f,g,h) which contains a vectorised expression of its parameters within it.

I'd like to add a new column: data$result <- with(data, myFun(A,B,C,D,E,F,G,H)) where A,B,C,D,E,F,G,H are column names of data. I'm using data.table but data.frame answers are appreciated too.

So far the parameter list (column names) can be tedious to type out, and I'd like to improve readability. Is there a better way?

> myFun <- function(a,b,c) a+b+c
> dt <- data.table(a=1:5,b=1:5,c=1:5)
> with(dt,myFun(a,b,c))
[1]  3  6  9 12 15

The ultimate thing I would like to do is:

 dt[isFlag, newCol:=myFun(A,B,C,D,E,F,G,H)]

However:

> dt[a==1,do.call(myFun,dt)]
[1]  3  6  9 12 15

Notice that the j expression seems to ignore the subset. The result should be just 3.

Upvotes: 1

Views: 89

Answers (2)

statquant
statquant

Reputation: 14390

Ignoring the subset aspect for now: df$result <- do.call("myFun", df). But that copies the whole df whereas data.table allows you to add the column by reference: df[,result:=myFun(A,B,C,D,E,F,G,H)].

To include the comment from @Eddi (and I'm not sure how to combine these operations in data.frame so easily) :

dt[isFlag, newCol := do.call(myFun, .SD)]

Note that .SD can be used even when you aren't grouping, just subsetting.

Or if your function is literally just adding its arguments together :

dt[isFlag, newCol := do.call(sum, .SD)]

This automatically places NA into newCol where isFlag is FALSE.

Upvotes: 4

Ferdinand.kraft
Ferdinand.kraft

Reputation: 12819

You can use

df$result <- do.call(myFun, df)

Upvotes: 3

Related Questions