Вычтите строки с числовыми значениями и игнорируйте NA - PullRequest
1 голос
/ 06 ноября 2019

У меня есть несколько фреймов данных, содержащих 18 столбцов с прибл. 50000 рядов. Каждая запись строки представляет собой измерение в определенном месте (= столбец), и данные содержат значения NA.

Мне нужно вычесть последовательные строки в столбце (например, row (i + 1) -row (i)) для определения пороговых значений, но мне нужно игнорировать (и сохранять) NA, так что только записи с числовыми значениями вычитаются друг из друга.

Я нашел очень полезные посты с data.table решениями дляодин столбец Итерация по столбцу, игнорирующая, но сохраняющая значения NA в R , и для операций с несколькими столбцами (например, Суммирование нескольких столбцов с помощью dplyr? ).

Однако мне не удалось объединить подходы, предложенные в SO (то есть применить diff к нескольким столбцам и игнорировать NA)

Вот пример df для иллюстрации и решения Iпопробовал:

library(data.table)

df <- data.frame(x=c(1:3,NA,NA,9:7),y=c(NA,4:6, NA,15:13), z=c(6,2,7,14,20, NA, NA, 2))

вот как это работает для одного столбца

 diff_x <- df[!is.na(x), lag_diff := x - shift(x)]  # actually what I want, but for more columns at once

и вот как я применяю функцию diff для нескольких столбцов с lapply

diff_all <- setDT(df)[,lapply(.SD, diff)]  # not exactly what I want because NAs are not ignored and  the difference between numeric values is not calculated 

Буду признателен за любые предложения (base, data.table, dplyr, ... решения) о том, как внедрить действительный !is.na или аналогичный оператор в эту вторую строку кода.

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

Определение вспомогательной функции делает вещи немного чище:

 lag_diff <- function(x) {
   which_nna <- which(!is.na(x))
   out <- rep(NA_integer_, length(x))
   out[which_nna] <- x[which_nna] - shift(x[which_nna])
   out
 }

cols <- c("x", "y", "z")
setDT(df)
df[, paste0("lag_diff_", cols) := lapply(.SD, lag_diff), .SDcols = cols]

Результат:

#     x  y  z lag_diff_x lag_diff_y lag_diff_z
# 1:  1 NA  6         NA         NA         NA
# 2:  2  4  2          1         NA         -4
# 3:  3  5  7          1          1          5
# 4: NA  6 14         NA          1          7
# 5: NA NA 20         NA         NA          6
# 6:  9 15 NA          6          9         NA
# 7:  8 14 NA         -1         -1         NA
# 8:  7 13  2         -1         -1        -18
0 голосов
/ 06 ноября 2019

Итак, вы ищете:

library("data.table")

df <- data.frame(x=c(1:3,NA,NA,9:7),y=c(NA,4:6, NA,15:13), z=c(6,2,7,14,20, NA, NA, 2))
setDT(df)
# diff_x <- df[!is.na(x), lag_diff := x - shift(x)]  # actually what I want, but

lag_d <- function(x) { y <- x[!is.na(x)]; x[!is.na(x)] <- y - shift(y); x }
df[, lapply(.SD, lag_d)]

или

library("data.table")

df <- data.frame(x=c(1:3,NA,NA,9:7),y=c(NA,4:6, NA,15:13), z=c(6,2,7,14,20, NA, NA, 2))
lag_d <- function(x) { y <- x[!is.na(x)]; x[!is.na(x)] <- y - shift(y); x }
as.data.frame(lapply(df, lag_d))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...