Как я могу изменить значения DF условно со значением из другого столбца - PullRequest
0 голосов
/ 07 мая 2018

У меня есть фрейм данных, в котором я хотел бы проверить, равняется ли значение столбца конкретному значению, и изменить его на значение из другого столбца. В приведенном ниже примере я хотел бы изменить все «0/0» на значение из 4-го столбца, чтобы первая строка была «A» такой же, как в строке 2, а в строке 3 - «C».

пример таблицы:

chr1A   63248   .   A   G   0/0 0/0 0/0 ./. 0/0
chr1A   80950   .   A   C   1/1 0/0 ./. 0/0 0/0
chr1A   81080   .   C   G   0/0 0/0 0/0 ./. 0/0
chr1A   81084   .   C   T   0/1 0/0 0/0 ./. 0/0 

Я пытался использовать этот код:

for(i in names(df)) {
  if(df[,i] == "0/0") {df[,i]<-df$V4}
}

но это не меняет все "0/0" в кадре данных.

Большое спасибо за любую помощь, Raz

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Можно использовать dplyr::mutate_at как:

library(dplyr)

df %>% mutate_at(vars(6:10), funs(ifelse(.=="0/0",df[,4],.)))

#      V1    V2 V3 V4 V5  V6 V7  V8  V9 V10
# 1 chr1A 63248  .  A  G   A  A   A ./.   A
# 2 chr1A 80950  .  A  C 1/1  A ./.   A   A
# 3 chr1A 81080  .  C  G   C  C   C ./.   C
# 4 chr1A 81084  .  C  T 0/1  C   C ./.   C

Данные:

df <- read.table(text =
                 "chr1A   63248   .   A   G   0/0 0/0 0/0 ./. 0/0
                 chr1A   80950   .   A   C   1/1 0/0 ./. 0/0 0/0
                 chr1A   81080   .   C   G   0/0 0/0 0/0 ./. 0/0
                 chr1A   81084   .   C   T   0/1 0/0 0/0 ./. 0/0",
                 stringsAsFactors = FALSE)
0 голосов
/ 07 мая 2018

Поскольку мы меняем только значения столбца с 6:10, просто зациклите их и замените их значением 4-го столбца

df[6:10] <- lapply(df[6:10], function(x) ifelse(x == "0/0", df[[4]], x))

Или это можно сделать без цикла, создав логическую матрицу, затем реплицировать 4-й столбец, чтобы сделать длины равными, и назначить элементам (на основе 'i1') значение 4-го столбца

i1 <- df[6:10] == "0/0"
df[6:10][i1]  <- df$V4[row(df[6:10])][i1]

В коде OP логическое выражение используется в if, но его длина больше 1, поэтому лучше использовать ifelse вместо if/else

for(i in names(df)[6:10]) {
    df[,i] <- ifelse(df[,i] == "0/0", df[[4]], df[,i])
 }
df
#     V1    V2 V3 V4 V5  V6 V7  V8  V9 V10
#1 chr1A 63248  .  A  G   A  A   A ./.   A
#2 chr1A 80950  .  A  C 1/1  A ./.   A   A
#3 chr1A 81080  .  C  G   C  C   C ./.   C
#4 chr1A 81084  .  C  T 0/1  C   C ./.   C
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...