2016-11-07 3 views
0

このような行列があります。0/1の値を入れ替えた行は、その行に複数の1の値がある場合の対応する列名です。

`  
     a b c d 
[1,] 1 0 0 0 
[2,] 1 0 0 0 
[3,] 1 0 0 0 
[4,] 1 0 0 0 
[5,] 1 0 0 0 
[6,] 1 0 0 0 
[7,] 1 0 0 0 
[8,] 1 1 0 0 
[9,] 1 1 0 0 
[10,] 1 1 0 0 
[11,] 0 1 0 1 
[12,] 1 1 0 1 
[13,] 1 1 0 1 
[14,] 1 1 0 1 
[15,] 0 1 0 1 
[16,] 0 1 0 1 
[17,] 0 1 0 1 
[18,] 0 1 0 1 
[19,] 0 1 1 0 
[20,] 0 1 0 0 
[21,] 1 1 1 1 
[22,] 1 1 1 1 
[23,] 1 0 1 1 
[24,] 1 0 0 1 
[25,] 1 0 0 1 
[26,] 1 0 1 1 
[27,] 1 0 1 0 
[28,] 0 0 1 0 
[29,] 0 0 1 0 
[30,] 0 0 1 1` 

再現するためのコード:

` 
mat1 <- as.matrix(cbind(c(rep(1,10),0,1,1,1,0,rep(0,5),rep(1,7),0,0,0),c(rep(0,7),rep(1,15),rep(0,8)),c(rep(0,18),1,0,1,1,1,0,0,rep(1,5)),c(rep(0,10),rep(1,6),1,1,0,0,rep(1,6),0,0,0,1))) 


colnames(mat1) <- c("a", "b", "c", "d") 

私がしたいことは例の8行目の最初の行と同様に1のより多くのそして1つの値がある場合は、各行にチェックすることです:

` 
    a b c d 
[8,] 1 1 0 0` 

次に、これらの1つの値を対応する列名に置き換えます。このよう

私はマトリックス構造を維持しながら、より多くのそれから1つの1の値がある行のすべての1つの値にこれを適用する
' 
     a b c d 
    [8,] a b 0 0` 
' 

1つ以上の値を持つ行を選択することはそれほど難しくありませんでした。対応する列名を選択することも管理していましたが、置き換えて管理できませんでした。 これは、私は誰もがこの問題で私を助けてとても親切だろう

` 
apply(mat1,1, function(x) { 
    #select rows with more then one 1 
    if(sum(x) > 1) { 
    #for every row with more than one 1; check if the value is 1 
    for (i in 1:4) { 
     if (x[i]==1) { 
     #this seems to print every column name I need 
     print(colnames(mat1)[i]) 
     #replacing should happen here I ques, but I can't get the location in the matrix. 

     } 
    } 
    } 
    }) 
` 

を行うために管理している何ですか?また、この二重ループよりも良い方法はもちろん歓迎ですが、私の問題には必要ありません。

+2

マトリックスには異なるクラスのエントリを含めることはできません。あなたは数値マトリックスを持っています。文字をそこに置くと**すべての**値は '文字'クラスに変換されます。これは、あなたの望むことですか? – Gregor

+0

また、あなたの共有データには実際には 'colnames'がありません... – Gregor

+0

すべての文字が文字になっても問題ありません。そしてあなたが正しいです、私はコードに列名を追加することを忘れました。私は今それをしました。 – BNS1993

答えて

2

あなたはこれを試すことができます。

col_n <- colnames(mat1) 
res <- apply(mat1,1, function(x) { 
    #select rows with more then one 1 
    if(sum(x) > 1) { 
    x[x == 1] <- col_n[x == 1] 
    } 
    return(x) 
}) 

res <- t(res) 
+0

これは、私が望むものを正確に行うための簡単な方法です。ありがとうございました。 – BNS1993

0

はグレゴールのアドバイスの後にコードをクリーンアップ:

# create the dataframe 
mat1 <- as.matrix(cbind(c(rep(1,10),0,1,1,1,0,rep(0,5),rep(1,7),0,0,0),c(rep(0,7),rep(1,15),rep(0,8)),c(rep(0,18),1,0,1,1,1,0,0,rep(1,5)),c(rep(0,10),rep(1,6),1,1,0,0,rep(1,6),0,0,0,1))) 

# use only rows satisfying your condition 
mat2 <- mat1[rowSums(mat1) > 1, ] 
# set up char matrix 
letterMat <- cbind(rep("a", nrow(mat2)), 
        rep("b", nrow(mat2)), 
        rep("c", nrow(mat2)), 
        rep("d", nrow(mat2))) 
# replace values in the char matrix 
letterMat[mat2 == 0] <- 0 
+1

'apply(mat1、1、sum)'は使わず、 'rowSums(mat1)'だけを使ってください。 – Gregor

+0

大きなアドバイス、ありがとう! – ira

+0

これは興味深い方法です。しかし、どこでmat3を作りますか? – BNS1993

0

これは非常に愚かであるが、仕事を取得します。

mat1 <- as.matrix(cbind(c(rep(1,10),0,1,1,1,0,rep(0,5),rep(1,7),0,0,0),c(rep(0,7),rep(1,15),rep(0,8)),c(rep(0,18),1,0,1,1,1,0,0,rep(1,5)),c(rep(0,10),rep(1,6),1,1,0,0,rep(1,6),0,0,0,1))) 
colnames(mat1) <- c("a","b","c","d") 
mat1sum <- rowSums(mat1) 
for (i in 1:dim(mat1)[1]) { 
if (mat1sum[i] > 1) { 
    for (j in 1:dim(mat1)[2]) { 
    if (mat1[i,j]==1) { 
     mat1[i,j] <- colnames(mat1)[j] 
    } 
    } 
} 
} 
+0

また興味深い方法。少しPythonのように見えます。ご回答有難うございます! – BNS1993

関連する問題