R data.table - удалить строки, соответствующие заданному маргиналу - PullRequest
1 голос
/ 07 февраля 2020

У меня следующая проблема. У меня есть data.table и подмножество столбцов M. У меня есть вектор x, определенный для M.

library(data.table)
data <- matrix(c(0,0,NA,1,0,1,NA,1,0,0,1,0,1,1,NA,NA,1,0,0,1,0,0,1,1,1,0,0,1,NA,0,1,1,0,1,1,1), byrow = T, ncol = 6, dimnames = LETTERS[1:6])
dt <- data.table(data)
dt
%     A B  C  D  E F
% 1:  0 0 NA  1  0 1
% 2: NA 1  0  0  1 0
% 3:  1 1 NA NA  1 0
% 4:  0 1  0  0  1 1
% 5:  1 0  0  1 NA 0
% 6:  1 1  0  1  1 1

M = LETTERS[2:5]
x <- dt[2,..M]
x
%    B C D E
% 1: 1 0 0 1

. Я хочу удалить все строки из dt с маргинальным значением M, равным x. Т.е. рядов нет. 2 и 4. И M, и x меняются во время программы. Результат для данных M и x будет:


   A B  C  D  E F
1: 0 0 NA  1  0 1
2: 1 1 NA NA  1 0
3: 1 0  0  1 NA 0
4: 1 1  0  1  1 1

Ответы [ 3 ]

5 голосов
/ 07 февраля 2020

data.table anti-join

dt[!x, on = M] # also works: dt[!dt[2], on = M]

#    A B  C  D  E F
# 1: 0 0 NA  1  0 1
# 2: 1 1 NA NA  1 0
# 3: 1 0  0  1 NA 0
# 4: 1 1  0  1  1 1

База R

eq2 <- Reduce('&', lapply(dt[, ..M], function(x) x == x[2]))

dt[-which(eq2),]
#    A B  C  D  E F
# 1: 0 0 NA  1  0 1
# 2: 1 1 NA NA  1 0
# 3: 1 0  0  1 NA 0
# 4: 1 1  0  1  1 1
1 голос
/ 07 февраля 2020

Другое базовое решение R

> subset(dt,!data.frame(t(dt[,..M])) %in% data.frame(t(x)))
   A B  C  D  E F
1: 0 0 NA  1  0 1
2: 1 1 NA NA  1 0
3: 1 0  0  1 NA 0
4: 1 1  0  1  1 1
1 голос
/ 07 февраля 2020

Не совсем вариант data.table, но с base R вы можете сделать:

data[rowSums(sweep(data[, M], 2, FUN = `==`, x), na.rm = TRUE) != length(x), ]

     A B  C  D  E F
[1,] 0 0 NA  1  0 1
[2,] 1 1 NA NA  1 0
[3,] 1 0  0  1 NA 0
[4,] 1 1  0  1  1 1
...