У меня такой же вопрос, как и решенный здесь, но мне нужно работать с data.table.
Каков наилучший способ data.table для фильтрации всех строк, где все конкретные/«релевантные» столбцы являются NA, неважно, что показывают другие «нерелевантные» столбцы (NA/или нет).
library(data.table)
df <- data.frame('epoch' = c(1,2,3),
'irrel_2' = c(NA,4,5),
'rel_1' = c(NA, NA, 8),
'rel_2' = c(3,NA,7)
)
df
#> epoch irrel_2 rel_1 rel_2
#> 1 1 NA NA 3
#> 2 2 4 NA NA
#> 3 3 5 8 7
setDT(df)
wrong <- na.omit(df, cols = 3:4)
Created on 2023-05-25 with reprex v2.0.2
Я хочу, чтобы только строка 2 была отфильтрована. Каким будет ваше решение?
Мы можем использовать patterns
, если определение «релевантности» ясно, или вы можете так же легко использовать вектор имен. Оттуда мы можем использовать rowSums(!is.na(.))
, чтобы найти хотя бы одно не-NA
значение.
library(data.table)
setDT(df)
df[df[, rowSums(!is.na(.SD)) > 0, .SDcols = patterns("^rel")],]
# epoch irrel_2 rel_1 rel_2
# <num> <num> <num> <num>
# 1: 1 NA NA 3
# 2: 3 5 8 7
Мы могли бы сделать это так:
df[!is.na(rel_1) | !is.na(rel_2)]
epoch irrel_2 rel_1 rel_2
1: 1 NA NA 3
2: 3 5 8 7
Вы можете решить проблему следующим образом:
df[!is.na(fcoalesce(rel_1, rel_2)),]
# or
df[!is.na(pmin(rel_1, rel_2, na.rm=TRUE)),]
epoch irrel_2 rel_1 rel_2
<num> <num> <num> <num>
1: 1 NA NA 3
2: 3 5 8 7
Использование dplyr
library(dplyr)
df %>%
filter(!if_all(starts_with("rel"), is.na))
epoch irrel_2 rel_1 rel_2
1 1 NA NA 3
2 3 5 8 7
Или с data.table
library(data.table)
setDT(df)[df[, !Reduce(`&`, lapply(.SD, is.na)),
.SDcols = patterns("^rel")]]
epoch irrel_2 rel_1 rel_2
1: 1 NA NA 3
2: 3 5 8 7