Как заменить NAs в середине и левой части каждой строки во фрейме данных значением?

#r

#r

Вопрос:

У меня есть фрейм данных, в котором в каждой строке есть NA. Некоторые находятся слева, некоторые в середине, а некоторые справа. Что-то вроде этого:

 a <- c(NA, NA, 1, NA)
b <- c(NA, 1,  1, NA)
c <- c(NA, NA, 1, 1)
d <- c(1, 1, NA, 1)
df <- data.frame(a, b, c, d)
df
# a  b  c  d
# NA NA NA 1
# NA 1  NA 1
# 1  1  1  NA
# NA NA 1  1
  

Я хотел бы заменить все NAS, которые находятся в середине и справа, на 0, но сохранить все NA, ведущие к 1 слева, как NA. Поэтому я хотел бы, чтобы эффективный способ (мой фрейм данных большой) имел этот фрейм данных:

 # a  b  c  d
# NA NA NA 1
# NA 1  0  1
# 1  1  1  0
# NA NA 1  1
  

Комментарии:

1. Не могли бы вы, пожалуйста, объяснить «середину»? Это относится к строке или столбцу?

2. Середина строки, как в случае со второй строкой. Под серединой я подразумеваю NAS, которые окружены 1 в строке.

3. Попробуйте df[] <- t(apply(df, 1, function(x) {i1 <- which(x == 1)[1]; x[i1:length(x)][is.na(x[i1:length(x)])] <- 0; x}))

4. Это сработало, и это было довольно быстро для моих больших данных. Спасибо.

Ответ №1:

Мы можем использовать apply для перебора строк, найти индекс первого появления 1. Затем замените NAs от этого элемента до последнего на 0

 df[] <- t(apply(df, 1, function(x) {
               i1 <- which(x == 1)[1]
               i2 <- i1:length(x)
               x[i2][is.na(x[i2])] <- 0
               x})) 
  

Или другой вариант

 df[] <-  t(apply(df, 1, function(x) replace(x, 
                 cumsum(x ==1 amp; !is.na(x)) >= 1 amp; is.na(x), 0)))