2016-07-03 2 views
2
   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 

У меня есть кадр данных, где некоторые значения из столбцов a и b соответствуют именам других столбцов. Я хочу заменить 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, как попытка:

Если предположить, что dataframe называется 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 
     } 
    } 
} 

Это циклы и использует grepl для возврата логического соответствия, если строка в a или b соответствует имени столбца.

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>), чтобы сделать ваш вопрос проще ответить ,

Смежные вопросы