Как правильно выполнить подмножество в RStudio?

#r #subset

#r #подмножество

Вопрос:

Я создал следующий фрейм данных:

 age <- c(21,35,829,2)
sex <- c("m","f","m","c")
height <- c(181,173,171,166)
weight <- c(69,58,75,60)
dat <- as.data.frame(cbind(age,sex,height,weight), stringsAsFactors = FALSE)
dat$age <- as.numeric(age)
dat
  

Теперь я хочу выбрать только те строки учащихся, которые старше 20 или младше 80.

Почему это работает : dat[dat$age<20| dat$age>80,] ; subset(dat, age < 20 | age > 80)

Но это не: dat[dat$age>20| dat$age<80,] ; subset(dat, age > 20 | age < 80)

Я могу подмножить строки, которые НЕ моложе 80 или старше 20, но не те, которые на самом деле находятся в этом интервале.

В чем ошибка?

Заранее спасибо.

Комментарии:

1. Попробуйте dat[dat$age %in% 20:80,]

2. Извините, мой ответ был неправильным. Я внес правки, чтобы сделать это правильным.

3. Это может быть логической проблемой: «старше 20 или моложе 80» отлично решается для всех, всегда. Нет такого (действительного) числа, которое не было бы одним из этих двух неравенств. (829 человек старше 20, 2 моложе 80.)

Ответ №1:

Потому что ваше состояние допускает практически любой возможный возраст. Подумайте об этом, ваши условия независимы (потому что вы используете | оператор), поэтому каждая строка, которая соответствует одному из ваших условий, выбирается вашим фильтром. Каждый возраст, который сейчас определен в вашем data.frame, превышает 20 лет, а если нет, то, безусловно, ниже 80.

Если вы хотите выбрать каждую строку, то есть возраст от 20 до 80 лет, вам следует изменить логический оператор. Чтобы сделать эти условия зависимыми, например, так:

 dat[dat$age>20 amp; dat$age<80,]
subset(dat, age > 20 amp; age < 80)
  

В результате этого:

   age sex height weight
1  21   m    181     69
2  35   f    173     58
  

Теперь, если вы хотите выбрать все строки, которые находятся за пределами этого интервала, вы можете отменить это логическое условие с помощью ! оператора, как было предложено @r2evans в разделе комментариев. Это было бы что-то вроде этого:

 dat[!(dat$age > 20 amp; dat$age < 80),]
subset(dat, !(age > 20 amp; age < 80))
  

В результате этого:

   age sex height weight
3 829   m    171     75
4   2   c    166     60
  

Комментарии:

1. В случае, если ориентация логики может привести к путанице (часто мне нужно просто подробно описать все, чтобы собрать все части вместе / исправить)… остальные строки являются subset(dat, !(age > 20 amp; age < 80)) .

2. Но вы думаете, что мой ответ сбивает с толку? Я не знаю, на это ли вы указываете здесь.

3. Нет, я не думаю, что ваш ответ сбивает с толку… Я думаю, что логика может сбивать с толку, на что указывает утверждение «старше 20 или моложе 80» . В целом это может сбивать с толку, и я думаю, что ваш ответ хорошо это объясняет. Смысл моего комментария был дополнением, чтобы попытаться помочь закрепить (по мнению OP), какая логика обеспечивает какой результат.

4. О да! Ты прав, меня тоже смутило это утверждение.

Ответ №2:

Почему бы не использовать фильтр dplyr?

 library(dplyr)

df_age <- dat %>%
  dplyr::filter(age > 20
                , age < 80)