2016-07-03 4 views
2
私は列AおよびBからいくつかの値が他の列の名前と一致したデータフレームを持っている
   a      b     P116 P127 P125 P107 P101 P220 P135         
1 P116,P115,P113,P120,P112, P128,P125,P127,P123,P126, NA NA NA NA NA NA NA 
2 P116,P115,P113,P120,P112, P128,P125,P127,P123,P126, NA NA NA NA NA NA NA 
3 P120,P117,P116,P115,P119,  P98,P94,P96,P99,P93,  NA NA NA NA NA NA NA 
4  P34,P36,P40,P39,P37, P108,P106,P107,P110,P109, NA NA NA NA NA NA NA 
5 P123,P127,P125,P118,P198, P135,P132,P134,P138,P131, NA NA NA NA NA NA NA 
6 P142,P148,P149,P140,P150,  P80,P81,P89,P87,P86,  NA NA NA NA NA NA NA 

で列を入力します。 NAのものを数字に置き換えたい: 1(カラム "a"の値がカラム3:9の名前と一致する場合)、0(カラム "a"、 "b"の値がカラム3の名前と一致しない場合:9)、-1(列 "b"の列の値が列3:9の名前と一致する場合)Rは - DF

これは次のようになります。

   a       b    P116 P127 P125 P107 P101 P220 P135       
1 P116,P115,P113,P120,P112, P128,P125,P127,P123,P126, 1 -1 -1 0 0 0 0 
2 P116,P115,P113,P120,P112, P128,P125,P127,P123,P126, 1 -1 -1 0 0 0 0 
3 P120,P117,P116,P115,P119,  P98,P94,P96,P99,P93,  1  0 0 0 0 0 0 
4  P34,P36,P40,P39,P37, P108,P106,P107,P110,P109, 0  0 0 -1 0 0 0 
5 P123,P127,P125,P118,P198, P135,P132,P134,P138,P131, 0  1 1 0 0 0 -1 
6 P142,P148,P149,P140,P150,  P80,P81,P89,P87,P86,  0  0 0 0 0 0 0 
+0

"a"と "b"の両方の列が一致するとどうなりますか? –

+0

このデータフレームでは起こっていません。 –

答えて

1

私はそれを適切にテストされていないのだが、大規模なデータセットに遅くなる可能性が高いのですが、ここでは私の非常に非R-ような試みです:dfと呼ばれ、あなたのデータフレームを想定し

for (row in 1:nrow(df)) { 
    for (col in 3:ncol(df)) { 
     if (grepl(colnames(df)[col], df[row, "a"])) { 
      df[row, col] <- 1 
     } else if (grepl(colnames(df)[col], df[row, "b"])) { 
      df[row, col] <- -1 
     } else { 
      df[row, col] <- 0 
     } 
    } 
} 

aまたはbの文字列が列名と一致する場合、ループスルーしてgreplを使用して論理一致を返します。

2

私たちは、これがテストされ、機能的なアプローチである

df[-(1:2)] <- Reduce(`+`,Map(`*`, lapply(c("a", "b"), function(nm) 
     do.call(rbind, lapply(strsplit(df[[nm]], ","), function(x) 
     +(names(df)[-(1:2)] %in% x)))), c(1, -1))) 
df 
#       a       b P116 P127 P125 P107 P101 P220 P135 
#1 P116,P115,P113,P120,P112, P128,P125,P127,P123,P126, 1 -1 -1 0 0 0 0 
#2 P116,P115,P113,P120,P112, P128,P125,P127,P123,P126, 1 -1 -1 0 0 0 0 
#3 P120,P117,P116,P115,P119,  P98,P94,P96,P99,P93, 1 0 0 0 0 0 0 
#4  P34,P36,P40,P39,P37, P108,P106,P107,P110,P109, 0 0 0 -1 0 0 0 
#5 P123,P127,P125,P118,P198, P135,P132,P134,P138,P131, 0 1 1 0 0 0 -1 
#6 P142,P148,P149,P140,P150,  P80,P81,P89,P87,P86, 0 0 0 0 0 0 0 
0

試すことができます。

df=data.frame(a=c(
    "P116,P115,P113,P120,P112,", 
    "P116,P115,P113,P120,P112,", 
    "P120,P117,P116,P115,P119,", 
    "  P34,P36,P40,P39,P37,", 
    "P123,P127,P125,P118,P198,", 
    "P142,P148,P149,P140,P150,"  
), 
    b=c(
    "P128,P125,P127,P123,P126,", 
    "P128,P125,P127,P123,P126,", 
    "  P98,P94,P96,P99,P93,", 
    "P108,P106,P107,P110,P109,", 
    "P135,P132,P134,P138,P131,",  
    "  P80,P81,P89,P87,P86," 
),  
    P116=NA, P127=NA, P125=NA, P107=NA, P101=NA, P220=NA, P135=NA, 
    stringsAsFactors=FALSE) 

ソリューションは、次のとおりです:

sel=lapply(as.list(df[, 1:2]), function(col) 
    t(sapply(col, function(x) match(strsplit(x, ",")[[1]], names(df)[-(1:2)], nomatch=0)))) 
dfm=as.matrix(df[, -(1:2)]) 
k=-1 
lapply(sel, function(selr){ 
    i<<-0; k<<-k*-1 
    apply(selr, 1, function(j) { 
     i <<- i+1 
     dfm[cbind(i,j)]<<- k 
    })} 
    ) 
dfm[is.na(dfm)]=0  
df[, -(1:2)]=dfm 

あなたが得る:

は、データフレームを考えると

df 
          a       b P116 P127 P125 P107 P101 P220 P135 
## 1 P116,P115,P113,P120,P112, P128,P125,P127,P123,P126, 1 -1 -1 0 0 0 0 
## 2 P116,P115,P113,P120,P112, P128,P125,P127,P123,P126, 1 -1 -1 0 0 0 0 
## 3 P120,P117,P116,P115,P119,  P98,P94,P96,P99,P93, 1 0 0 0 0 0 0 
## 4  P34,P36,P40,P39,P37, P108,P106,P107,P110,P109, 0 0 0 -1 0 0 0 
## 5 P123,P127,P125,P118,P198, P135,P132,P134,P138,P131, 0 1 1 0 0 0 -1 
## 6 P142,P148,P149,P140,P150,  P80,P81,P89,P87,P86, 0 0 0 0 0 0 0 

、次回の使用dput(<your dataframe>)は答えることがあなたの質問をより簡単にするためにしてください。

関連する問題