पृष्ठभूमि

मुझे एक सूची के उपयोग के साथ दो कार्यों के लिए तर्क पारित करने के लिए do.call का उपयोग करने में दिलचस्पी है। do.call समाधान को अप्रयुक्त तर्कों को अनदेखा करना चाहिए।

उदाहरण

my_sum <- function(a, b) {
    a + b
}

my_exp <- function(c, d) {
    c^d
}

args_to_use <- as.list(1:4)
names(args_to_use) <- letters[1:4]

my_wrapper <- function(fun_args = args_to_use) {
    res_one <- do.call(my_sum, fun_args)
    res_two <- do.call(my_exp, fun_args)
    res_one + res_two
}

स्वाभाविक रूप से, उदाहरण विफल हो जाता है क्योंकि दोनों कार्यों के लिए अनावश्यक तर्क पारित किए जाते हैं।

वांछित परिणाम

my_wrapper_two <- function(fun_args = args_to_use) {
    res_one <- do.call(my_sum, fun_args[1:2]) # Only a, b
    res_two <- do.call(my_exp, fun_args[3:4]) # Only c, d
    res_one + res_two
}
my_wrapper_two()
# 84

मांगा समाधान

मैं फ़ंक्शन तर्कों के आधार पर सब्मिटिंग ऑपरेशंस [1:2] और [3:4] को स्वचालित रूप से निष्पादित करना चाहता हूं।


टिप्पणियाँ

एक दृष्टिकोण जिसके बारे में मैं सोच रहा था वह तर्कों की वांछित सूची बनाने के लिए names(formals(my_exp)) का उपयोग करेगा:

my_wrapper_three <- function(fun_args = args_to_use) {
    res_one <- do.call(my_sum, fun_args[names(formals(my_sum))])
    res_two <- do.call(my_exp, fun_args[names(formals(my_exp))])
    res_one + res_two
}
my_wrapper_three()

यह सुरुचिपूर्ण नहीं दिखता है और मैं सोच रहा हूं कि क्या कोई और बुद्धिमान समाधान है?

अद्यतन

मैं जिस समाधान के साथ आया हूं वह इस प्रकार है:

do_call_on_existing <- function(fun, args_list) {
    fun_args <- names(formals(fun))
    viable_args <- args_list[fun_args]
    viable_args <- Filter(Negate(is.null), viable_args)
    do.call(fun, viable_args)
}

Filter / Negate बिट फ़ंक्शन को विफल होने से रोकता है जहां my_sum में अतिरिक्त तर्क हो सकते हैं जिसके परिणामस्वरूप तर्क सूची null तत्व वापस आ जाएगी। तो कोड काम कर सकता है:

my_sum <- function(a = 999, b = 999, c = 999) {a + b + c}
my_nms <- list(a = 1, b = 2) 
do_call_on_existing(my_sum, my_nms)
2
Konrad 5 अक्टूबर 2020, 12:48

1 उत्तर

सबसे बढ़िया उत्तर

इसे आज़माएं (... आपको my_sum में कितने भी तर्क पारित करने की अनुमति देता है लेकिन केवल a और b आपकी परिभाषा के अनुसार उपयोग किए जाते हैं):

my_sum <- function(a, b, ...) {
    a + b
}

my_exp <- function(c, d, ...) {
    c^d
}

args_to_use <- as.list(1:4)
names(args_to_use) <- letters[1:4]

my_wrapper <- function(fun_args = args_to_use) {
    res_one <- do.call(my_sum, fun_args)
    res_two <- do.call(my_exp, fun_args)
    res_one + res_two
}
1
ekoam 5 अक्टूबर 2020, 12:50