2011-01-19 13 views
5

R için yeniyim ve işlev ailesini uygulamasında bir tanıtmaya çalışıyorum. Özellikle, 2 karakter vektörünü, "ana bilgisayar" ve "konuk" u (aynı uzunlukta olması gerekmeyen) kabul edecek ve bana "ana bilgisayar" ile aynı uzunlukta bir indeks vektörü döndürecek olan daha yüksek mertebeden bir işlev yazmaya çalışıyorum. ", konuktaki endekslerine karşılık gelen sonuç öğeleriyle birlikte (NA olmasa bile).Bir indeks vektörü döndürmek için bu işlevi nasıl düzenleyebilirim?

host <- c("A","B","C","D") 
guest <- c("D","C","A","F") 

matchIndices <- function(x,y) 
{ 
    return(match(x,y)) 
} 

Bu kod beklendiği gibi 3 döndürür: (? Sapply) Bu bir özlü uygulamak fonksiyonu ile değiştirmek mümkün olmak istiyorum döngü

matchIndices(host[1],guest) 

Bu kod, aşağıdaki çıktıyı üretmesiyle "çalışır", ancak sonucun bir vektör olmasını gerçekten istiyorum ve uygulama işlevlerinden birinin hile yapacağı bir önsezim var. Sadece nasıl yazılacağıma takıldım. Herhangi bir yardım en çok takdir edilecektir. Teşekkürler.

3; A; NA; B; 2; C; 1; D;

cevap

8
host <- c("A","B","C","D") 
guest <- c("D","C","A","F") 

matchIndices <- function(x,y) { 
    return(match(x,y)) 
} 

One (verimsiz) yolu (sadece sapply(host, match, guest) bu basitleştirmek olabilir dikkat ama bu bu tür bir şey yaklaşan genel bir yolunu göstermektedir) bağımsız değişken olarak guest ileterek host vektörü üzerinde sapply şudur:

:
> sapply(host, matchIndices, guest) 
A B C D 
3 NA 2 1 

Bununla birlikte, bu, bir vektör ilk bağımsız değişken kabul olarak match kullanılarak şirketinden yapılabilir Eğer gerçekten isimler istiyor Bir fonksiyonun

matchIndices2 <- function(x, y) { 
    matched <- match(x, y) 
    names(matched) <- x 
    return(matched) 
} 

içine sarılmış olabilir

> matched <- match(host, guest) 
> names(matched) <- host 
> matched 
A B C D 
3 NA 2 1 

> matchIndices2(host, guest) 
A B C D 
3 NA 2 1 

dönen 0

çıkış dosyası olarak adlandırılmış vektör istiyorsanız, ve eşleşmeler dizilerin bir vektörüne yapışmış, o zaman:

> paste(match(host, guest), host, sep = ";") 
[1] "3;A" "NA;B" "2;C" "1;D" 
+1

sadece yapabileceği 'sapply (ana bilgisayar, maç, konuk) ', matchIndices' –

+0

@Prasad'ı tanımlamanıza gerek yok Evet, bunu yapabilirdim ama bu şekilde bir kullanıcı işlevinin nasıl özüleceğini göstermek için bunu bıraktım. Bunun gibi bıraktığım sebep, bu, bir vektörün ilk argümanını kabul ettiği için, "match" ile doğrudan yapılabilirdi. Güncellenmiş cevabımı görün. –

+0

Bu harika. Çok teşekkür ederim. "maç (ev sahibi, konuk)" mükemmel. Bu kadar küçük olabileceğini farketmedim. – user297400

3

sen şu do.call, paste, match olarak host;guestNum formatında çıkış vektörü kullanırsınız isterseniz:

> do.call(paste, list(host, sapply(host, match, guest), sep = ';'))                      
[1] "A;3" "B;NA" "C;2" "D;1" 
+2

Dediğim gibi, burada hiç bir şekilde "sapply" gerekmez; "match" bir vektörün ilk argümanını alır, bu yüzden bunu 'do.call' e (macun, liste (host, match (host, guest), sep = ';')) basitleştirebiliriz, fakat bu biraz overkill gibi görünüyor paste (match (host, guest), host, sep = ";") 'veya' paste (host, match (host, guest), sep = ";") 'dır? –

+0

çok true @Gavin, bu en basit yol –

+0

darn, haklısın. Yani 'do.call (yapıştırma, liste (host, maç (host, konuk), sep ="; "))' –

2
sapply(host , function(x) which(guest==x)) 
$A 
[1] 3 

$B 
integer(0) 

$C 
[1] 2 

$D 
[1] 1 


unlist(sapply(host , function(x) which(guest==x))) 

    A C D 
    3 2 1 

paste(host, sapply(host , function(x) which(guest==x)), sep=":", collapse=" ") 
[1] "A:3 B:integer(0) C:2 D:1" 
İlgili konular