2011-01-19 7 views
5

私はRが新しく、適用される関数ファミリのハンドルを取得しようとしています。具体的には、2つの文字ベクトル「host」と「guest」(同じ長さである必要はない)を受け取り、「host」と同じ長さのインデックスベクトルを返す高次関数を記述しようとしています"、得られた要素はゲストのインデックスに対応します(存在しない場合はNA)。どのようにインデックスベクトルを返すためにこの関数をベクトル化できますか?

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

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

このコードは期待通りに3を返します(?sapply)これは私が簡潔適用する機能と交換できるようにしたいと思いループがある

matchIndices(host[1],guest) 

このコードは、以下の出力を生成するという点で "機能する"が、実際には結果がベクトルになりたいのですが、適用関数の1つがそのトリックを行うことがわかっています。私はちょうどそれを書く方法に立ち往生しています。どんな助けでも大歓迎です。ありがとう。

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

答えて

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

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

ワン(非効率的な)方法は、引数(あなただけsapply(host, match, guest)にこれを簡素化することができますが、これはこの種のものに近づいての一般的な方法を示しています)としてguestに渡し、hostベクトル上sapplyにある:

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

しかし、これは、ベクトルの最初の引数を受け入れるようmatchを使用して直接を行うことができますあなたが本当には名前が必要場合は機能

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

にラップすることができ

> 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 

を返す0

あなたが出力として名前のベクトルをしたい場合は、マッチは文字列のベクトルにまとめられ、次に:

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

あなただけ行うことができます 'sapply(ホスト、試合、ゲスト) '、matchIndices'を定義する必要はありません –

+0

@Prasadはい、あなたはこの方法でユーザー関数をどのようにサプリメントするかを示すことだったのですが、このままにしました。なぜなら、これはベクトルの最初の引数を受け入れるので、これはすべて 'match'を使って直接行うことができたからです。私の更新された答えを見てください。 –

+0

これは素晴らしいです。どうもありがとうございました。 "match(host、guest)"は完璧です。私はそれがコンパクトであるかもしれないことに気付かなかった。 – user297400

3

あなたは次のdo.callpastematchとしてhost;guestNum形式で出力ベクトルは、あなたが使用したい場合:

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

私が言ったように、ここでは「サプリー」は必要ありません。 'match'はベクトルの最初の引数を取るので、これを' do.call(paste、list(host、match(host、guest)、sep = ';')) ')に単純化することができます。 (host、guest)、sep = ";") 'または' paste(host、match(host、guest)、sep = ";") 'それはしませんか? –

+0

非常に真実@ギャビン、それは最も簡単な方法です –

+0

ダーン、そうです。あなたが畳み込まれたRコードを読むのが好きなら 'do.call(paste、list(host、match(host、guest)、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" 
関連する問題