2015-07-13 59 views
2

我希望使用substitute()在表達式中執行變量替換,而不計算表達式。例如,我有:使用替代方法在R表達式中執行變量替換

expr1 <- expression(if(x){ 
    return(y) 
} else { 
    return(z) 
}) 

我想什麼做的就是分配得到以下結果爲 「表達式1」:

expression(if(cos(x)){ 
    return(y) 
} else { 
    return(z) 
}) 

通過做這樣的事情:

expr2 <- substitute(expr1, list(x=cos(x))) 

但是這不起作用,因爲替代品並沒有評估它的第一個參數。所以我只是找回原來的變量:

expr1 

現在here它說,做替換分配給一個變量的表情,我必須執行substitute()兩次,後面eval(),就像這樣:

expr2 <- eval(substitute(substitute(e, list(x = cos(x))), list(e = expr1))) 

當我執行該語句,我得到分配到「表達式2」的表現,但它不包含所需的替代:

expression(if (x) { 
    return(y) 
} else { 
    return(z) 
}) 

我可以申請什麼語法「表達式1」,使我得到的結果,我想分配到「表達式2」,即:

expression(if (cos(x)) { 
    return(y) 
} else { 
    return(z) 
}) 

回答

2

這似乎這樣的伎倆

do.call('substitute', list(expr1[[1]], list(x=quote(cos(x))))) 
# if (cos(x)) { 
#  return(y) 
# } else { 
#  return(z) 
# } 

首先我使用do.call將未評估的表達式作爲參數傳遞給substitute(),而不是雙-。其次,expression()真的很像一個容器對象。您真的只想更改表達式第一個元素的代碼塊。你可能已經避免了expression(),只是用來quote()避免「拆箱」

expr2 <- quote(if(x){ return(y) } else { return(z) }) 
do.call('substitute', list(expr2, list(x=quote(cos(x))))) 

這兩個將返回一個類型的類「如果」。如果您需要,可以將其包裝在as.expression()中。

as.expression(do.call('substitute', list(expr1[[1]], list(x=quote(cos(x)))))) 
# expression(if (cos(x)) { 
#  return(y) 
# } else { 
#  return(z) 
# }) 
+0

非常感謝你。這兩種解決方案(你的和小的)產生一個「if」類​​對象。我確實想要保留這個表達式,但是當我將expr2(即:expression(expr2))包裝好後,我得到了「expression(expr2)」而不是「expression(if(cos(x)) ...)「。顯然我沒有正確包裝。任何指導? – user3990797

+0

@ user3990797對不起。我的意思是你可以在'do.call()'周圍使用'as.expression()'。我已經更新了我的答案。 – MrFlick

+0

沒問題,很高興幫助和學習了一些東西。我也在我的答案中添加了'as.expression()'註釋。 –

0

你必須通過包裝它嵌套substitution()加入的x = quote()函數裏面添加cos(x):每文檔,可以使用子集[[[,或$表達。您必須在超級替代調用中使用[[子集表達式對象。試試這個:

expr2 <- eval(substitute(substitute(e, list(x=quote(cos(x)))), list(e = expr1[[1]]))) 

expr2 
#if (cos(x)) { 
# return(y) 
#} else { 
# return(z) 
#} 

設置expr2作爲表達式,請致電:as.expression(expr2)

+3

你不需要在那裏有一個'x ='嗎?我複製/粘貼這個,但它並沒有改變我的任何東西。仍然'if(x)' – MrFlick

+0

嗯,這很奇怪,我只是再次運行它,現在它返回沒有cos(x)的表達式。不知道發生了什麼,試圖修復現在:/ –

+0

@MrFlick我想我現在明白了:) –