2012-04-04 22 views
5

मैं lapply कॉल की एक श्रृंखला का उपयोग करने की कोशिश कर रहा हूं, जो कि करीबी कार्यों की एक सूची बनाने के लिए कॉल करता है, जो आदर्श रूप से अंतिम lapply कॉल पर अंतिम वांछित मान देता है। करीबी काम करता है, लेकिन lapply दूसरे एप्लिकेशन के बाद हमेशा सूची में अंतिम तत्व लागू होता प्रतीत होता है।बार-बार कॉलिंग के बाद बंद होने में परिवर्तनीय मूल्य क्यों खो रहे हैं?

उदाहरण:

curry <- function(fn, ...) { 
    arglist <- list(...) 
    function(...) { 
    do.call(fn, append(arglist, list(...))) 
    } 
} 
# rcurry is used only to init the first lapply. 
rcurry <- function(v1, fn, ...) { 
    arglist <- append(list(v1), list(...)) 
    function(...) { 
    do.call(fn, append(arglist, list(...))) 
    } 
} 

myadd <- function(a,b,c) { 
    a+b+c 
} 

यह अपेक्षा के अनुरूप काम करता है:

# this does give the desired output: 
# curry.a.b <- list(curry(curry.a[[1]], 1), curry(curry.a[[2]], 1)) 
curry.a.b <- lapply(curry.a, curry, 1) 
curry.a.b[[1]](2) 
curry.a.b[[2]](2) 

# > [1] 1003 
# > [1] 1003 

यह एक तरह प्रतीत नहीं होता:

# you can achieve the same by closure: 
# curry.a <- lapply(c(10, 1000), FUN = function(a) { curry(myadd, a) }) 
curry.a <- lapply(list(10, 1000), rcurry, myadd) 
curry.a[[1]](1,2) 
curry.a[[2]](1,2) 

# > [1] 13 
# > [1] 1003 

curry की अगली lapply "गुंजाइश mangles" curry या rcurry फ़ंक्शन का परिणाम। roxygen का Curry फ़ंक्शन का उपयोग करना वही काम करता है। curry.a को ऊपर बंद करके या curry.a <- list(curry(myadd, 10), curry(myadd, 1000)) का उपयोग करके भी इसका परिणाम बनाते हैं।

और निश्चित रूप से अंतिम करी:

# it doesn't work if you re-define this: 
# curry.a.b <- list(curry(curry.a[[1]], 1), curry(curry.a[[2]], 2)) 
curry.a.b.c <- lapply(curry.a.b, curry, 2) 
lapply(curry.a.b.c, do.call, list()) 

# > [1] 1003 
# > [1] 1003 

यहाँ क्या हो रहा है?

+2

'lapply' एक नए माहौल में' FUN' मूल्यांकन करता है। मुझे लगता है कि इसके साथ कुछ करने के लिए है। –

+0

मुझे लगता है कि उत्तर टॉमी के जवाब में है जैसे http://stackoverflow.com/questions/9950144/access-lapply-index-names-inside-fun/9950734#comment12707459_9950734 –

+0

जोशुआ गर्म है, कोहस्के इसे नाखून करता है। आप सभी को धन्यवाद। –

उत्तर

2

fncurry में फ़ंक्शन के दायरे में मूल्यांकन नहीं किया गया है और इसलिए यह promise है। आप इसे force तो आप प्राप्त कर सकते हैं कि आप क्या उम्मीद:

curry <- function(fn, ...) { 
    force(fn) 
    arglist <- list(...) 
    function(...) { 
    do.call(fn, append(arglist, list(...))) 
    } 
} 

तो,

> curry.a.b <- lapply(curry.a, curry, 1) 
> curry.a.b[[1]](2) 
[1] 13 
> curry.a.b[[2]](2) 
[1] 1003 
> 
> curry.a.b.c <- lapply(curry.a.b, curry, 2) 
> lapply(curry.a.b.c, do.call, list()) 
[[1]] 
[1] 13 

[[2]] 
[1] 1003 

अधिक आंतरिक रूप से, lapply एक स्थानीय चर X कि समारोह के प्रत्येक कॉल द्वारा संदर्भित किया जाता है उत्पन्न करता है। X का मूल्यांकन lapply पर कॉल करते समय प्रत्येक फ़ंक्शन में मूल्यांकन नहीं किया जाता है, X वादा करता है। lapply पर कॉल करने के बाद, Xlapply से सभी फ़ंक्शन कॉल में समान (यानी, अंतिम) मान देता है। तो lapply साथ समान है:

f0 <- function(i) function() i 
f1 <- function(i) {force(i); function() i} 

f <- local({ 
r0 <- list() 
r1 <- list() 
for (i in 1:2) { 
    r0[[i]] <- f0(i) 
    r1[[i]] <- f1(i) 
} 
list(r0 = r0, r1 = r1) 
}) 

तो,

> f$r0[[1]]() 
[1] 2 
> f$r1[[1]]() 
[1] 1 
> f$r0[[2]]() 
[1] 2 
> f$r1[[2]]() 
[1] 2 
+0

100% बुल्स आंख। धन्यवाद! मैंने वास्तव में सोचा कि बंद करने का वादा है, इसलिए मैंने 'बंद कर दिया <- फ़ंक्शन (...) {do.call (fn, संलग्न करें (arglist, list (...))}; बल (बंद करें); वापसी बंद करें' बेशक, यह काम नहीं किया। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^