2017-11-17 17 views
1

データフレームの列を通って実行されるコードを記述し、その中に数字が1の場合はTRUEを返し、その値を列と同じサイズのベクトルに送信します。データフレーム以下のコードスニペットを簡略化する方法があるかどうかを知りたいのですが、いくつかの数字を繰り返す必要があります。コードを簡略化するR

n1 <- (tab[, 2]==1| tab[, 3]==1 | tab[, 4]==1 | tab[, 5]==1 | 
    tab[, 6]==1 | tab[, 7]==1 | tab[, 8]==1 | tab[, 9]==1 | 
    tab[, 10]==1 | tab[, 11]==1 | tab[, 12]==1 | tab[, 13]==1 | 
    tab[, 14]==1 | tab[, 15]==1 | tab[, 16]==1) 
+0

適用ファミリの機能を参照してください。あなたのR端末に '?apply'または'?lapply'と打ち込んで、Rの世界へようこそ! – JMT2080AD

+0

IsraelMotta、あなたの質問を解決する答えがありますか?そうであれば、エチケットは、特定の答えの左側にあるチェックマークを選択することによって、あなたが好みの答えを「受け入れる」ことを示唆しています。 (そうでない場合は、フィードバックをお願いします。)ありがとう! – r2evans

答えて

1

その他のコメントと回答はうまくいきますが、data.frameを扱うときに悪い行為を促すことを推奨しています。まず第一に、applyrowSumsmatrixがデータとして期待されており、data.frameが与えられれば喜んでそのようなことになります。 data.frame列のいずれかがcharacterの場合、すべての列はcharacterに変換されます。一部の操作は、実際には== "1" ...となるため、期待どおりに動作します(たとえば、== 1など)。ただし、丸め誤差の影響で望ましくない効果が生じることがあります。一例として、

n <- 20 
set.seed(2) 
tab <- data.frame(
    a = as.character(sample(n, replace = FALSE)), 
    b1 = sample(5, size = n, replace = TRUE), 
    b2 = sample(5, size = n, replace = TRUE), 
    stringsAsFactors = FALSE 
) 
str(tab) 
# 'data.frame': 20 obs. of 3 variables: 
# $ a : chr "4" "14" "11" "3" ... 
# $ b1: int 4 2 5 1 2 3 1 2 5 1 ... 
# $ b2: int 5 2 1 1 5 4 5 2 3 5 ... 

apply(tab, 1, function(y) any(y == 1)) 
# [1] FALSE FALSE TRUE TRUE FALSE FALSE TRUE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE TRUE 
apply(tab, 1, sum) 
# Error in FUN(newX[, i], ...) : invalid 'type' (character) of argument 

rowSums(tab == 1) 
# [1] 0 0 1 2 0 0 1 0 0 1 2 2 0 0 0 0 0 1 0 1 
rowSums(tab) 
# Error in rowSums(tab) : 'x' must be numeric 

これに対処するためのいくつかの簡単な方法があります。あなたの例を考えると、列2:16は数値で、あなたが心配しているようです。 (前者はかなり特定され、後者は他の機能に拡張することができます)

rowSums(tab[,2:16] == 1)      # Frank's comment 
apply(tab[,2:16], 1, function(y) any(y == 1)) # suggested by You-leee's answer 

:そのような場合、あなたは安全のいずれかを使用することができます。一度常に

​​

を行うことができる唯一の非numericがある場合、第3の技術は、列が選択した実行時に決定することです:

isnum <- sapply(tab, is.numeric) 
Reduce(`|`, lapply(tab[isnum], function(y) any(y == 1))) 

これは少し複雑だった、復帰理由lapplylistですが、それでも正常に動作します。 isnumの使用は、greplのようなものを使用して、列名にも基づいている可能性があることを理解してください。このメソッドは、どちらの列も一致しないとエラーにならないという点で、かなり堅牢です。

+1

ありがとうございました。このソリューションは完全に機能しました。データフレームであることが最も安全なソリューションだと思います。 –

2

一つの可能​​な解決策は以下の通りです:それはあなたを与えるだろうこの例では

tab <- data.frame(a = 1:10, b = 2:11) 

apply(tab == 1, 1, function(x) { 
    Reduce("|", x) 
}) 

:あなたは==のためにデータフレームで1つの番号を検索して|オペレータにその行を削減出力に含ま:

[1] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 

または1つでも簡単な解決策は以下のとおりです。

apply(tab, 1, function(x) { 
    any(x == 1) 
}) 
+0

または 'rowSums(tab == 1)> 0' – Frank

+0

' apply.'または 'rowSums'を' data.frame'で使用するのは面倒で誤りです。あなたがすべての数字であると確信しているならば、それらの関数が完全に機能するような、「マトリックス」ではない*ほとんどの理由はありません。間違ってデータに数字以外の数字があると、両方の機能が動作しなくなります。 (この単純なケースでは、単純な '=='は必ずしも破られるわけではありませんが、私の前提が立っています。) – r2evans