Как мне найти 1-е значение, отличное от NA, в строке? - PullRequest
1 голос
/ 25 февраля 2020

Предположим, у меня есть следующее:

df <- data.frame(dt=c(as.Date('2019-02-02'), as.Date('2019-02-04'), as.Date('2019-02-05'), as.Date('2020-03-04')), v1=c(1,2,NA,NA), v2=c(NA,3,4,NA), v3=c(NA,NA,3,5), v4=c(2, 4, 6, NA))
> read.zoo(df)
           v1 v2 v3 v4
2019-02-02  1 NA NA  2
2019-02-04  2  3 NA  4
2019-02-05 NA  4  3  6
2020-03-04 NA NA  5 NA

Я хотел бы найти первое не-NA значение в каждой строке после столбца, который имел значение.

Так, например, для '2019-02-02':

  • есть значение в v1, равное 1, v2 имеет NA, поэтому мы пропускаем, v3 имеет NA так мы пропускаем, но v4 НЕ является NA, поэтому я хотел бы вернуть его значение, 2 для строки 1, столбец 1.
  • Глядя на следующий столбец, v2, в той же строке это NA, поэтому мы пропускаем это, так как это не число
  • v3 также NA, поэтому мы пропускаем это.
  • v4 НЕ является NA, но после него нет столбцов, поэтому мы возвращаем NA.

Поэтому наша 1-я строка будет выглядеть так:

c1 c2 c3 c4
2  NA NA NA

Пройдя по всем строкам в этом примере, я ожидаю, что результат будет:

             c1 c2 c3 c4
1 2019-02-02  2 NA NA NA
2 2019-02-04  3  4 NA NA
3 2019-02-05 NA  3  6 NA
4 2020-03-04 NA NA NA NA

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

ПРИМЕЧАНИЕ: я бы предпочел решение base-R с использованием zoo

Ответы [ 2 ]

3 голосов
/ 25 февраля 2020

Вот решение с применением пользовательской функции:

res = t(apply(df[-1], 1, function(x) {
     val = which(!is.na(x))
     x[val[-length(val)]] = x[val[-1]]
     x[val[length(val)]] = NA
     return(x)
     }
  ))

cbind(df[1], res)
#           dt v1 v2 v3 v4
# 1 2019-02-02  2 NA NA NA
# 2 2019-02-04  3  4 NA NA
# 3 2019-02-05 NA  3  6 NA
# 4 2020-03-04 NA NA NA NA
1 голос
/ 26 февраля 2020

Я не уверен, как это сделать с base R. Но в tidyverse:

df %>% 
gather(key, value, -dt) %>% 
arrange(dt, key) %>% 
mutate(key2 = as.numeric(substr(key, 2, 2))) %>% 
filter(!is.na(value)) %>% group_by(dt) %>% 
mutate(ind = lag(key2, default = NA), index = paste0("c", ind)) %>% 
ungroup() %>% 
filter(!is.na(ind)) %>% 
select(dt, index, value) %>% 
spread(index, value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...