Подтвердить что ты не робот

Subset dataframe несколькими логическими условиями строк для удаления

Я хотел бы подмножить (фильтровать) фрейм данных, указав, какие строки не (!) сохранить в новом фрейме данных. Вот упрощенная модель данных:

data
v1 v2 v3 v4
a  v  d  c
a  v  d  d
b  n  p  g
b  d  d  h    
c  k  d  c    
c  r  p  g
d  v  d  x
d  v  d  c
e  v  d  b
e  v  d  c

Например, если строка столбца v1 имеет "b", "d" или "e", я хочу избавиться от этой строки наблюдений, создавая следующий файл данных:

v1 v2 v3 v4
a  v  d  c
a  v  d  d
c  k  d  c    
c  r  p  g

Я был успешным в подмножестве, основанном на одном условии за раз. Например, здесь я удаляю строки, где v1 содержит "b":

sub.data <- data[data[ , 1] != "b", ]

Однако у меня много таких условий, поэтому делать это по одному не желательно. Мне не удалось выполнить следующие действия:

sub.data <- data[data[ , 1] != c("b", "d", "e")

или

sub.data <- subset(data, data[ , 1] != c("b", "d", "e"))

Я пробовал и другие вещи, например !%in%, но это, похоже, не существует. Любые идеи?

4b9b3361

Ответ 1

! должен находиться за пределами инструкции:

data[!(data$v1 %in% c("b", "d", "e")), ]

  v1 v2 v3 v4
1  a  v  d  c
2  a  v  d  d
5  c  k  d  c
6  c  r  p  g

Ответ 2

Попробуйте это

subset(data, !(v1 %in% c("b","d","e")))

Ответ 3

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

subset(my.df, my.df$v1 != "b" & my.df$v1 != "d" & my.df$v1 != "e")

Это не изящно и требует больше кода, но может быть более читаемым для новых пользователей R. Как указано в комментарии выше, subset - это "удобная" функция, которая наилучшим образом используется при работе в интерактивном режиме.

Ответ 4

data <- data[-which(data[,1] %in% c("b","d","e")),]

Ответ 5

Этот ответ больше предназначен для объяснения, почему, а не как. Оператор '==' в R векторизован так же, как оператор '+'. Он соответствует элементам того, что находится на левой стороне, к элементам того, что находится справа, для каждого элемента. Например:

> 1:3 == 1:3
[1] TRUE TRUE TRUE

Здесь первый тест 1==1, который имеет значение ИСТИНА, второй 2==2 и третий 3==3. Обратите внимание, что это возвращает FALSE в первом и втором элементах, потому что порядок неправильный:

> 3:1 == 1:3
[1] FALSE  TRUE FALSE

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

>  1:2 == 1:3
[1]  TRUE  TRUE FALSE
Warning message:
In 1:2 == 1:3 :
  longer object length is not a multiple of shorter object length

Здесь первое совпадение 1==1, затем 2==2 и, наконец, 1==3 (FALSE), потому что левая сторона меньше. Если одна из сторон - это только один элемент, то это повторяется:

> 1:3 == 1
[1]  TRUE FALSE FALSE

Правильный оператор для проверки того, находится ли элемент в векторе, действительно '%in%', который векторизован только для левого элемента (для каждого элемента в левом векторе он проверяется, если он является частью любого объекта в правом элементе).

В качестве альтернативы вы можете использовать '&' для объединения двух логических операторов. '&' принимает два элемента и проверяет элементно, если оба имеют значение ИСТИНА:

> 1:3 == 1 & 1:3 != 2
[1]  TRUE FALSE FALSE

Ответ 6

my.df <- read.table(textConnection("
v1 v2 v3 v4
a  v  d  c
a  v  d  d
b  n  p  g
b  d  d  h    
c  k  d  c    
c  r  p  g
d  v  d  x
d  v  d  c
e  v  d  b
e  v  d  c"), header = TRUE)

my.df[which(my.df$v1 != "b" & my.df$v1 != "d" & my.df$v1 != "e" ), ]

  v1 v2 v3 v4
1  a  v  d  c
2  a  v  d  d
5  c  k  d  c
6  c  r  p  g

Ответ 7

sub.data<-data[ data[,1] != "b"  & data[,1] != "d" & data[,1] != "e" , ]

Больше, но просто для понимания (я думаю) и может использоваться с несколькими столбцами, даже с !is.na( data[,1]).