2012-08-03 13 views
10

To czysta ciekawostka (więcej informacji na temat Reduce). Są lepsze sposoby na osiągnięcie tego, co robię i nie jestem nimi zainteresowany.używanie Reduce/do.call z ifelse

Niektóre osoby używają serii zagnieżdżonych poleceń ifelse do przekodowywania/wyszukiwania czegoś. Może wygląda to tak:

set.seed(10); x <- sample(letters[1:10], 300, T) 
ifelse(x=="a", 1, 
    ifelse(x=="b", 2, 
    ifelse(x=="c", 3, 
    ifelse(x=="d", 4, 5)))) 

Czy istnieje sposób, aby użyć do.call lub Reduce z ifelse aby otrzymać pracę trochę bardziej elokwentnie?

+3

Świetne pytanie. Oczywiście, w praktyce coś takiego jak 'sapply (x, funkcja (x) switch (x, a = 1, b = 2, c = 3, d = 4, 5' jest prawdopodobnie najczystsze –

+0

@Richie Dzięki. ' d faktycznie podchodzimy do tego z tabelą wyszukiwania przy użyciu środowisk lub standardowego indeksowania z 'match' ale chciałem zobaczyć, czy' Reduce' lub 'do.call' może być zastosowany do tego problemu –

+0

Jak w:' match (x, litery [1: 4], nomatch = 5) ' –

Odpowiedz

3

Spróbuj tego:

> library(gsubfn) 
> strapply(x, ".", list(a = 1, b = 2, c = 3, d = 4, 5), simplify = TRUE) 
    [1] 5 4 5 5 1 3 3 3 5 5 5 5 2 5 4 5 1 3 4 5 5 5 5 4 5 5 5 3 5 4 5 1 2 5 5 5 5 
[38] 5 5 5 3 3 1 5 3 2 1 5 2 5 4 5 3 5 2 5 5 5 4 5 1 2 5 4 5 5 5 5 1 3 1 5 5 5 
[75] 1 5 4 5 3 3 5 5 3 5 3 1 5 3 2 2 5 5 5 5 4 5 3 5 5 1 4 1 4 5 5 5 5 5 5 5 5 
[112] 5 2 5 5 5 3 5 5 5 2 4 4 5 3 3 5 4 5 5 5 1 5 3 4 3 5 5 2 5 5 3 1 5 2 5 5 5 
[149] 1 5 5 2 1 2 4 2 2 3 5 2 5 5 5 5 5 3 5 5 5 5 5 5 5 5 5 5 2 3 5 4 4 2 5 5 5 
[186] 5 5 5 5 2 1 1 1 5 5 5 5 3 5 5 3 5 5 5 2 5 5 5 3 5 5 5 5 5 1 5 5 5 5 2 2 5 
[223] 5 5 4 3 4 5 5 4 5 5 5 3 5 3 5 5 5 5 4 5 5 1 5 5 2 5 5 5 2 5 5 3 2 5 4 5 2 
[260] 5 5 3 5 5 1 4 3 5 4 5 2 5 5 3 5 5 5 5 5 1 1 5 2 5 1 5 5 5 5 5 5 5 5 5 5 5 
[297] 5 1 5 2 
+1

Nie widzę' ifelse' i funkcja 'do.call' lub' Reduce' w dowolnym miejscu :) –

+5

Wypróbuj 'do.call <- strapply', a następnie powtórz powyższe z' do.call' zamiast ' strapply'. –

+0

To rzeczywiście działa :) –

0

Oto próba. Nie jest ani piękny, ani nie używa ifelse:

f <- function(w,s) { 
    if(is.null(s$old)) 
    w$output[is.na(w$output)] <- s$new 
    else 
    w$output[w$input==s$old] <- s$new 
    return(w) 
} 

set.seed(10); x <- sample(letters[1:10], 300, T) 

subst <- list(
    list(old="a", new=1), 
    list(old="b", new=2), 
    list(old="c", new=3), 
    list(old="d", new=4), 
    list(old=NULL, new=5) 
) 
workplace <- list(
    input=x, 
    output=rep(NA, length(x)) 
) 

Reduce(f, subst, workplace)