4

これは、この質問に関連しています。

大きなデータ フレーム内の列のサブセットの名前を変更したいと考えています。次のコードは、列X4X5X6およびX7をそれぞれ gradekgrade1grade2、および に名前変更することを期待しています。grade3

set.seed(1)
in.df <- data.frame( matrix( rnorm(60), ncol=10) )
names(in.df) <- ifelse( names(in.df) %in% c('X4', 'X5', 'X6', 'X7'),
                         paste('grade', c('k',1:3), sep=''),
                         names(in.df) )

でも、

> names(in.df)
 [1] "X1"     "X2"     "X3"     "grade3" "gradek" "grade1" "grade2" "X8"    
 [9] "X9"     "X10"   

それでも

> paste('grade', c('k',1:3), sep='')
[1] "gradek" "grade1" "grade2" "grade3"

順序が保持されていないことを示しています。This threadmatchは、代わりに使用すると機能することを示唆してい%in%ますが、この場合は機能しません。(おそらく、R の他のバージョンではそうでした。私のインストール済みバージョン (2.15.3) では、ヘルプ ページで、それが via で定義されてmatchいることが示唆されているため、切り替えても役に立たないでしょう。)%in%match

どんな助けでも大歓迎です!

受け入れられた回答 この回答は、名前の変更の問題を解決します。 この回答は、奇妙な動作がリサイクルによるものであることを説明しています。

4

2 に答える 2

5

%in%動作するはずですが、おそらくmatchの方が優れています。

以下を検討してください。「A」と「B」はあなたのを表しますnames(in.df)。の結果を使用して、「matchme」の値をこの順序で置き換えたいと考えていますpaste('grade', c('k',1:3), sep='')

異なる出力を比較します。

A <- B <- c("X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10")
matchme <- c('X4', 'X7', 'X6', 'X5')
A[A %in% matchme] <- paste('grade', c('k',1:3), sep='')
A
#  [1] "X1"     "X2"     "X3"     "gradek" "grade1" "grade2" "grade3" "X8"    
#  [9] "X9"     "X10"  
B[match(matchme, B)] <- paste('grade', c('k',1:3), sep='')
B
#  [1] "X1"     "X2"     "X3"     "gradek" "grade3" "grade2" "grade1" "X8"    
#  [9] "X9"     "X10"   
于 2013-04-19T18:24:18.460 に答える
4

アナンダの答えは、あなたが望むことをする方法の良いアプローチを提供します. 代わりに、期待した結果ではなく、実行した結果が得られた理由についての質問に答えます。

名前が順不同に見える理由は、ifelse動作方法と引数のリサイクルに関連しています。の 3 つの引数を見てみましょうifelse

> list(names(in.df) %in% c('X4', 'X5', 'X6', 'X7'),
+      paste('grade', c('k',1:3), sep=''),
+      names(in.df))
[[1]]
 [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE

[[2]]
[1] "gradek" "grade1" "grade2" "grade3"

[[3]]
 [1] "X1"  "X2"  "X3"  "X4"  "X5"  "X6"  "X7"  "X8"  "X9"  "X10"

ifelse最初の引数が TRUE であるか FALSE であるかに基づいて、選択する対応する要素を決定します。しかし、2 番目の引数は最初の引数ほど長くないため、適切な長さに再利用されます。これらを data.frame に入れて並べて見やすくし、2 番目の名前のセットを手動で展開すると、次のようになります。

> data.frame(test = names(in.df) %in% c('X4', 'X5', 'X6', 'X7'),
+            `TRUE` = rep(paste('grade', c('k',1:3), sep=''),length=10),
+            `FALSE` = names(in.df))
    test  TRUE. FALSE.
1  FALSE gradek     X1
2  FALSE grade1     X2
3  FALSE grade2     X3
4   TRUE grade3     X4
5   TRUE gradek     X5
6   TRUE grade1     X6
7   TRUE grade2     X7
8  FALSE grade3     X8
9  FALSE gradek     X9
10 FALSE grade1    X10

したがって、新しい名前の 4 番目、5 番目、6 番目、および 7 番目の要素が使用されます。これは、引数の再利用により、4 番目、1 番目、2 番目、および 3 番目に対応します。

于 2013-04-19T18:32:17.920 に答える