2017-08-25 32 views
-1

我有character中的表達式,這些表達式應該在data.table(不重要的上下文中)中進行評估。 爲了確保所有需要的列都存在,我想提取R表達式中的所述列。如何從R表達式中提取要在data.frame上下文中進行評估的變量

我想要什麼:

library(data.table) 
DT <- data.table(p001=rnorm(10),p002=rnorm(10),p003=rnorm(10)) 
expr <- 'p001+mean(p001,na.rm=TRUE)-weighted.mean(p002,w=p003)+someRandomOtherColumn' 

# DT[,test:=p001+mean(p001,na.rm=TRUE)-weighted.mean(p002,w=p003)+someRandomOtherColumn] 
# would fail as p004 is not in the columns 

基本上我正在尋找一種方式(可能是一個正則表達式),它將從exprp001,p002,p003,someRandomOtherColumn提取。

我就可以了看法: 我看到它的方式,我應該能夠捕捉到p001,p001,TRUE,p002,p003,someRandomOtherColumn一些正則表達式,將內f(,)捕捉的東西,然後篩選「允許的」列名(TRUE不是在案件)。

嵌套f(,,)不是一個問題,因爲我可以調用相同的函數遞歸和嵌套f(,(),)也很好。

我有什麼: 從現在這就是我,這可以做的工作,但這種感覺不好

expr <- 'p001+mean(p001,na.rm=TRUE)-weighted.mean(p002,w=p003)+someRandomOtherColumn' 
clean <- function(string) gsub(string, pattern='[_|\\.|a-zA-z]+\\(([^)]*)\\)', replacement='\\1', perl=TRUE) 
clean(expr) 
[1] "p001+p001,na.rm=TRUE-p002,w=p003+someRandomOtherColumn" 
# Then I can remove =* than split on ,|+|-|* 
+0

如果你只想進去'F中的值()','p004'不應該在預期的結果。 @Cath,我認爲在這種情況下'\\ bp \\ d + \\ b'將會過度匹配。必須有自定義邊界。 –

+0

@statquant你能保證'f(...)'裏面沒有'('和')'嗎? –

+1

@WiktorStribiżew可以嵌套'f()',但這很好,我可以遞歸調用相同的函數 – statquant

回答

3

當您添加~到你的表情,你可以創建一個有效的r ...式表達:

expr <- '~ p001+mean(p001,na.rm=TRUE)-weighted.mean(p002,w=p003)+someRandomOtherColumn' 

該字符串可被轉換爲一個公式與as.formula。此後,變量名可以用all.vars提取:

all.vars(as.formula(expr)) 
# [1] "p001"    "p002"    "p003"    "someRandomOtherColumn" 
+0

LOL非常聰明!希望我不會找到一個反例 – statquant

+0

@statquant謝謝。請注意,這種方法比使用regex更強大,因爲它使用了R的表達式解析器。 –

+0

不知道爲什麼我得到了低估...無論如何謝謝 – statquant

相關問題