2016-10-20 6 views
3

Предположим, что у меня есть этот фрейм данныхДинамически заменить значения столбца на основе имеющихся значений из другого столбца

set.seed(2) 
df <- data.frame(c1 = sample(c(0:3,NA), 50, replace = T), c2 = sample(c(0:3,NA), 50, replace = T), 
       c3 = sample(c(0:3,NA), 50, replace = T), c4 = sample(c(0:3,NA), 50, replace = T)) 

head(df) 
    c1 c2 c3 c4 
1 0 0 1 0 
2 3 0 2 1 
3 2 3 NA NA 
4 0 NA NA 1 
5 NA 1 1 3 
6 NA NA 2 1 

Когда c4 является 0, я хотел бы заменить его на следующей доступной стоимости без НС в c3. Если c3 - NA, то c2 и т. Д.

Я пытаюсь научиться, как это сделать, поэтому не просто бросайте ответ! Если все в порядке, предложите возможные решения. Заранее спасибо.

Edit:

Ожидаемый результат:

head(df) 
    c1 c2 c3 c4 
1 0 0 1 1 # This would be the only difference with the head output from above 
2 3 0 2 1 
3 2 3 NA NA 
4 0 NA NA 1 
5 NA 1 1 3 
6 NA NA 2 1 
+0

Ну, c4 не является 0, поэтому замена не требуется. – cimentadaj

+1

'df $ c4 <- apply (df, 1, function (x) { ifelse (x [4] == 0, x [! Is.na (x)] [длина (x [! Is.na (x)]) - 1], x [4]) }) '? – Abdou

+0

Что делать, если следующее значение 'NA' равно нулю, как row9 вашего' df'? – 989

ответ

3

Это, как вы можете сделать это без обхвата по каждой строке:

c4 <- ncol(df) 
inds <- max.col(!is.na(df[,-c4]) & df[,-c4]!=0, "last") 
zeroinds <- which((df[,c4]==0)==T) 
df[zeroinds,c4] <- df[cbind(zeroinds,inds[zeroinds])] 

head(df, 10) 

    # c1 c2 c3 c4 
# 1 0 0 1 1 
# 2 3 0 2 1 
# 3 2 3 NA NA 
# 4 0 NA NA 1 
# 5 NA 1 1 3 
# 6 NA NA 2 1 
# 7 0 3 NA NA 
# 8 NA NA 2 2 
# 9 2 3 0 3 
# 10 2 3 0 1 

Вот как:

  1. c4 в последней колонке
  2. Мы находим первое не-NA и ненулевое значение для каждой строки перед c4
  3. Найти эти строки с нулем в c4 и положить его в zeroinds
  4. Replace нулей в zeroinds с первым не-NA и ненулевое значение для каждой строки
+0

@cimentadaj Обратите внимание, что в вашем кадре данных есть несколько строк, в которых нет не-NA, отличных от нуля после нуля в значении 'c4', например row41. – 989

+1

Да, но в моей реальной проблеме есть. Это было действительно умное решение. Это помогло много и даже больше, потому что я это понимаю. – cimentadaj