最初にあなたのデータ:
c <- c("9", "286593", "C", "C/C", "C/A", "A/A")
# Note: In your original data, you had a space in "G/A", which I did remove.
# If this was no mistake, we would also have to deal with the space.
d <- c("9", "334337", "A", "A/A", "G/A", "A/A")
e <- c("9", "390512", "C", "C/C", "C/C", "C/C")
dat <- data.frame(rbind(c,d,e))
ここで、使用可能なすべての文字を含むベクトルを生成します。
values <- c("A", "C", "G", "T")
dat$X3 <- factor(dat$X3, levels=values) # This way we just ensure that it will later on be possible to compare the reference values to our generated data.
# Generate all possible combinations of two letters
combinations <- expand.grid(f=values, s=values)
combinations <- cbind(combinations, v=with(combinations, paste(f, s, sep='/')))
メイン関数は、各列の各組み合わせの正しい列を見つけ、これを参照列 3 と比較します。
compare <- function(col, val) {
m <- match(col, combinations$v)
2 - (combinations$f[m] == val) - (combinations$s[m] == val)
}
最後に、apply を使用して、変更が必要なすべての列に対して関数を実行します。6 を実際の列数に変更することをお勧めします。
dat[,4:6] <- apply(dat[,4:6], 2, compare, val=dat[,3])
これまでの他のソリューションと比較して、このソリューションは文字列比較を使用せず、純粋に因子レベルに基づくアプローチであることに注意してください。どちらがより優れたパフォーマンスを発揮するかを見るのは興味深いでしょう。
編集
私はいくつかのベンチマークを行いました:
test replications elapsed relative user.self sys.self user.child sys.child
1 arun 1000000 2.881 1.116 2.864 0.024 0 0
2 fabio 1000000 2.593 1.005 2.558 0.030 0 0
3 roland 1000000 2.727 1.057 2.687 0.048 0 0
5 thilo 1000000 2.581 1.000 2.540 0.036 0 0
4 tyler 1000000 2.663 1.032 2.626 0.042 0 0
これにより、私のバージョンはわずかに速くなります。ただし、違いはほとんどないため、おそらくすべてのアプローチで問題ありません。公平を期すために、因子レベルを追加する部分のベンチマークは行いませんでした。これも同様に行うと、おそらく私のバージョンが除外されます。