Как создать новый столбец на основе NAs и нулей нескольких других столбцов в R?

#r

#r

Вопрос:

У меня есть набор данных, который отслеживает доходы миллионов компаний за многие годы. Данные выглядят как упрощенная версия ниже:

 dat <-   data.frame(Company = c("a","b","c","d","e","f"), rev_2001 = c(NA, 20, 10, NA, NA, 10), 
     rev_2002 = c(10, 50, 20, 30, NA, 0), rev_2003 = c(20, NA, 0, NA, NA, 30), rev_2004 = c(NA, 60, 0, 50, NA, 50), rev_2005 = c(NA, 30, NA, 0, NA, 60))
  

Я хотел создать переменную (новый столбец, который мы могли бы обозначить как ‘closure.year’), которая отражала бы последний год, когда доход компании отличался от 0 или NA. Я борюсь с двумя вещами:

  1. Тот факт, что я хочу игнорировать как нули, так и NAs, но я не хочу преобразовывать NAs в нули или наоборот;
  2. Как вы можете видеть, данные содержат некоторые нули и NAs не только за последние наблюдаемые годы, но и за некоторые промежуточные годы. Если бы у компании был доход через год с 0 или NA, этот год не рассматривался бы как закрытие.год. Кроме того, если компания не прекратила получать доходы, переменная закрывается.год будет NA.

В общем, я хотел бы иметь окончательные данные, которые выглядели бы так:

введите описание изображения здесь

Большое вам спасибо!

Ответ №1:

Вы можете попробовать приведенный ниже код

 z <- do.call(cbind,Reduce(`|`,rev(replace(dat,is.na(dat),0)[-1]),accumulate = TRUE))
x <- max.col(z>0,"first")
dat$closure.year <- as.numeric(gsub(".*_","",names(dat[-1])[ncol(dat)-replace(x,x == 1,NA)]))
  

что дает

 > dat
  Company rev_2001 rev_2002 rev_2003 rev_2004 rev_2005 closure.year
1       a       NA       10       20       NA       NA         2003
2       b       20       50       NA       60       30           NA
3       c       10       20        0        0       NA         2002
4       d       NA       30       NA       50        0         2004
5       e       NA       NA       NA       NA       NA           NA
6       f       10        0       30       50       60           NA
  

Ответ №2:

Как насчет преобразования из широкого формата в длинный?

 df_long <- gather(df,year,value,rev_2001:rev_2005,factor_key=TRUE)
df_long %>% group_by(Company) %>% top_n(1, value)
  

Вам нужно будет добавить еще немного логики для обработки ваших условий 0 и NA, но этот подход может помочь.