I faced a problem when exercising with data.table. Here is my problem. I wrote a simple subtraction function:
我在使用数据表进行锻炼时遇到了一个问题。这是我的问题。我写了一个简单的减法函数
minus <- function(a, b){
return(a - b)
}
My dataset is a simple data.table:
我的数据集是一个简单的数据集。
dt <- as.data.table(data.frame(first=c(5, 6, 7), second=c(1,2,3)))
dt
first second
1 5 1
2 6 2
3 7 3
I would like to write another function,
我想写另一个函数,
myFunc <- function(dt, FUN, ...){
return(dt[, new := FUN(...)])
}
The usage is simply:
使用很简单:
res <- myFunc(dt, minus, first, second)
and the result would be the following:
其结果如下:
res
first second new
1: 5 1 4
2: 6 2 4
3: 7 3 4
How can I archive such a goal? Thanks!
我怎样才能实现这样的目标呢?谢谢!
2 个解决方案
#1
2
Maybe there's a better way, but you can try something like this:
也许有更好的方法,但是你可以试试这样的方法:
myFunc <- function(indt, FUN, ...) {
FUN <- deparse(substitute(FUN)) # Get FUN as a string
FUN <- match.fun(FUN) # Match it to an existing function
dots <- substitute(list(...))[-1] # Get the rest of the stuff
# I've used `copy(indt)` so that it doesn't affect your original dataset
copy(indt)[, new := Reduce(FUN, mget(sapply(dots, deparse)))][]
}
(Note that this is very specific to how you've created your minus()
function.)
(请注意,这对于如何创建减()函数非常特殊。)
Here it is in action:
它的行动如下:
res <- myFunc(dt, minus, first, second)
dt ## Unchanged
# first second
# 1: 5 1
# 2: 6 2
# 3: 7 3
res
# first second new
# 1: 5 1 4
# 2: 6 2 4
# 3: 7 3 4
#2
0
Here is a solution with do.call
:
这里有一个解决方法。
myFunc <- function(dt, FUN, ...){
arg.names <- as.character(match.call()[-(1:3)])
copy(dt)[, "new" := do.call(FUN, lapply(arg.names, function(x) get(x)))]
}
#test
myFunc(dt, minus, first, second)
# first second new
#1: 5 1 4
#2: 6 2 4
#3: 7 3 4
#1
2
Maybe there's a better way, but you can try something like this:
也许有更好的方法,但是你可以试试这样的方法:
myFunc <- function(indt, FUN, ...) {
FUN <- deparse(substitute(FUN)) # Get FUN as a string
FUN <- match.fun(FUN) # Match it to an existing function
dots <- substitute(list(...))[-1] # Get the rest of the stuff
# I've used `copy(indt)` so that it doesn't affect your original dataset
copy(indt)[, new := Reduce(FUN, mget(sapply(dots, deparse)))][]
}
(Note that this is very specific to how you've created your minus()
function.)
(请注意,这对于如何创建减()函数非常特殊。)
Here it is in action:
它的行动如下:
res <- myFunc(dt, minus, first, second)
dt ## Unchanged
# first second
# 1: 5 1
# 2: 6 2
# 3: 7 3
res
# first second new
# 1: 5 1 4
# 2: 6 2 4
# 3: 7 3 4
#2
0
Here is a solution with do.call
:
这里有一个解决方法。
myFunc <- function(dt, FUN, ...){
arg.names <- as.character(match.call()[-(1:3)])
copy(dt)[, "new" := do.call(FUN, lapply(arg.names, function(x) get(x)))]
}
#test
myFunc(dt, minus, first, second)
# first second new
#1: 5 1 4
#2: 6 2 4
#3: 7 3 4