2012-11-12 15 views
6

Mam operator logiczny i wartość liczbową, którą chcę przekazać jako pojedynczy element do instrukcji w funkcji (słyszę setki użytkowników R jęczących, nigdy nie robię tego, ale mam sytuację, którą czuję jest w porządku).Przesyłanie argumentów znaków i ocena

DF <- mtcars 
overlap = "> 2" 
as.numeric(rowSums(DF[, 1:6]) overlap) 

Jak mogę sprawić, że trzecia linia prace jak:

as.numeric(rowSums(DF[, 1:6]) > 2) 

wiem, że to prawdopodobnie eval i parse ale nigdy ich używać tak naprawdę nie rozumiem, jak ich używać tutaj.

+0

Czy można przejść przez nakładanie jako listę zawierającą porównanie i próg? – mnel

+0

@mlin No, ponieważ nakładanie się może oznaczać jeszcze więcej rzeczy. Musi to być wprowadzanie znaków. –

Odpowiedz

7

Coś

Olap <- unlist(strsplit(overlap, " ")) 
Thresh <- as.numeric(Olap[2]) 
Comp <- match.fun(Olap[1]) 
Comp(rowSums(DF[,1:6]), Thresh) 

Alternatywą jest eval i analizować, jak sugeruje

What <- rowSums(DF[,1:6]) 

textcall <- sprintf(" What %s", overlap) 

exprcall <- parse(text = textcall) 

eval(exprcall) 
+0

Myślę, że potrzebujesz 'unlist', ale to może być podejście, które podejmuję. Zobaczmy, co jeszcze ma think tank. –

+0

dziękuję Byłem naprawdę zainteresowany na początku, jak używać 'eval'' parsowania 'i to było pouczające ale myślę, że pierwsze podejście, które sugerujesz może być lepsze. +1 Dam ci trochę, żeby ludzie odpowiedzieli, ale już mam funkcję ustawioną przy użyciu twojej pierwszej sugestii. –

+0

4 upvotes i żadne inne rozwiązania nie mówią mi, że to jest znacznik wyboru. Przesłałem już funkcję do github. Działa ładnie. Dzięki za twój pomysł. –

7

Trzeba przekonwertować cały wyraz ciąg znaków, a następnie przekonwertować analizowany tekst do wyrażenia. Na koniec wywołaj funkcję eval() w wyrażeniu.

np

overlap <- "> 2" 

# Convert to string 
exprAsString <- paste0("as.numeric(rowSums(DF[, 1:6]) ", overlap, ")") 

# Convert to expression, using parse 
expr <- as.expression(parse(text=exprAsString)) 

# Then call eval() 
eval(expr) 

Potwierdzenie to działa:

identical(eval(expr), as.numeric(rowSums(DF[, 1:6]) > 2)) 
# [1] TRUE 
1

Wydaje mi się, że choć rozwiązanie @mnel „s jest dobry, jest to sytuacja, która może zostać rozwiązany poprzez stworzenie fikcyjna funkcja wewnątrz głównej funkcji i użycie ciągu wejściowego (overlap) jako argumentu do modyfikacji body(dummy_function). To może być o wiele czystsze.