r разница между значениями столбца, отличного от NA - PullRequest
1 голос
/ 02 октября 2019

Мне нужно рассчитать разницу между значениями не-NA в строке. Например, если есть значения только в точках a, c и e, а значения в b и d равны NA, мне нужно вычислить разницу между c и a, e и c и оставить разницу между b и a ид и с пустым. d1 - это разница между значением не-NA в b и ближайшим значением не-NA слева (которое должно быть значением не-NA в a). d2 - это разница между значением не-NA в c и ближайшим значением не-NA слева. d3 - это разница между значением не-NA в d и ближайшим значением не-NA слева. d4 - это разница между значением не-NA в e и ближайшим значением не-NA слева.

Я думаю, что мне не хватает некоторых функций R, доступных для использования в этой ситуации. Я попытался написать ряд условий ifelse, в которых предыдущей точкой данных является NA, и это оказывается очень длинным оператором ifelse. df$d1<-ifelse(!is.na(df$a and !is.na(df$b), df$b-df$a) Но чем дальше я получаю от a, тем сложнее становятся ifelse утверждения. Я также попытался написать df$d1<-(!is.na(df$b))-(!is.na(df$a)) И результат не в разнице, а в том, является ли первая точка данных NA или нет (я получаю 0, 1, -1 в столбце d1).

Вот как структурирована моя исходная база данных:

```a<-c(10, 20, NA, 40, 50, 60)
b<-c(5, NA, 6, 7, NA, 8)
c<-c(NA, 4, 5, NA, 7, 8)
d<-c(NA, 9, 8, 7, 6, 5)
e<-c(3, 4, NA, 5, 6, 7)
df<-data.frame(a, b, c, d, e)```

Вот как мне нужен результат:

```d1<-c('-5','' ,'' , '-33','', '-52')
d2<-c('', '-16', '-1', '', '-43', '0')
d3<-c('', '5', '3', '0', '-1', '-3')
d4<-c('-2', '-5', '', '-2', '0', '2')
df1<-data.frame(d1, d2, d3, d4)```

1 Ответ

1 голос
/ 02 октября 2019

Вот вариант. Мы перебираем строки с помощью pmap (или apply из base R с MARGIN = 1), получаем diff интервал смежных элементов, отличных от NA ('i1'), связываем строки (pmap_dfr), select имена столбцов в правильном порядке и rename столбцы

library(dplyr)
library(stringr)
library(purrr)
pmap_dfr(df,  ~ {
       x <- c(...)
      i1 <- !is.na(x)
       diff(x[i1]) %>% 
    as.list}) %>%       
  select(sort(names(.))) %>%
  rename_all(~ str_c('d', seq_along(.)))
# A tibble: 6 x 4
#     d1    d2    d3    d4
#  <dbl> <dbl> <dbl> <dbl>
#1    -5    NA    NA    -2
#2    NA   -16     5    -5
#3    NA    -1     3    NA
#4   -33    NA     0    -2
#5    NA   -43    -1     0
#6   -52     0    -3     2

ПРИМЕЧАНИЕ. Здесь по умолчанию отсутствующие элементы будут заполнены NA. Лучше не использовать пустые строки (""), так как он меняет тип столбца с numeric на character


Если у нас есть только строки NA, найдите

pmap_dfr(df,  ~ {
     x <- c(...)
    i1 <- !is.na(x)
    if(any(i1)) {
     diff(x[i1]) %>% 
     as.list
    } else set_names(rep(list(NA_real_), length(x)-1), names(x)[-1])}) %>%       
  select(sort(names(.))) %>%
  rename_all(~ str_c('d', seq_along(.)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...