использование% in% для подстановки data.table - PullRequest
2 голосов
/ 11 апреля 2020

У меня есть data.table

library(data.table)
DT <- data.table(a=c(1,2,3,4), b=c(4,4,4,4), x=c(1,3,5,5))
> DT
   a b x
1: 1 4 1
2: 2 4 3
3: 3 4 5
4: 4 4 5

, и я хотел бы выбрать строки, где x равно a или b. Очевидно, я мог бы использовать

> DT[x==a | x==b]
   a b x
1: 1 4 1

, который дает правильный результат. Тем не менее, я подумал, что со многими столбцами следующее должно работать точно также:

> DT[x%in%c(a,b)]
   a b x
1: 1 4 1
2: 2 4 3

, но это дает другой результат, который не является интуитивным для меня. Кто-нибудь может помочь?

Ответы [ 3 ]

4 голосов
/ 11 апреля 2020

Выражение

 DT[x==a | x==b]

возвращает все строки в DT, где значения в x и a равны или x и b равны. Это желаемый результат.

С другой стороны,

 DT[x%in%c(a,b)]

возвращает все строки, где x соответствует любое значение в c(a, b), а не только соответствующее ценность. Таким образом, ваша вторая строка появляется, потому что x == 3 и 3 появляются (где-то) в a.

2 голосов
/ 11 апреля 2020

Мы можем использовать Reduce с .SDcols для нескольких столбцов. Укажите интересующие столбцы в .SDcols, затем l oop над .SD (Подмножество Data.table), сделайте сравнение (==) с 'x', и Reduce это в один логический вектор с |

DT[DT[, Reduce(`|`, lapply(.SD, `==`, x)), .SDcols = a:b]]
#   a b x
#1: 1 4 1
1 голос
/ 13 апреля 2020

Другой способ - использовать rowSums

DT[rowSums(DT[,.SD,.SDcols=-'x']==x)>0,]
#   a b x
#1: 1 4 1

. Вы можете изменить значение на rowMeans...==1, если хотите выбрать строки, в которых все столбцы равны x

...