как мне использовать ifelse для группировки диапазона переменных

#r

#r

Вопрос:

в моем наборе данных у меня есть переменная с именем ref, которая находится в диапазоне от 0 до 7. У каждого участника есть оценка. Я хотел бы сгруппировать его так, чтобы 0-3 было «низким», а 4-7 — «высоким».

Итак, я попытался создать новую переменную и попытался использовать функцию ifelse

 control_vs_fast$refsplit <- (ifelse(control_vs_fast$reflection >= 0 amp; control_vs_fast$reflection <=3, 'low', ifelse(control_vs_slow$reflection >3, 'high', 'no')))
 

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

Извините, если это было неясно, я новичок в R: (

РЕДАКТИРОВАТЬ: большое всем спасибо!

Ответ №1:

Это место, которое cut хорошо работает.

 control_vs_fast <- data.frame(reflection = c(-1:5))
control_vs_fast
#   reflection
# 1         -1
# 2          0
# 3          1
# 4          2
# 5          3
# 6          4
# 7          5
 

По умолчанию cut возвращает метки с использованием математической записи открытых / закрытых концов:

 cut(control_vs_fast$reflection, c(-Inf, 0, 3, Inf))
# [1] (-Inf,0] (-Inf,0] (0,3]    (0,3]    (0,3]    (3, Inf] (3, Inf]
# Levels: (-Inf,0] (0,3] (3, Inf]
 

Мы можем удалить метки и перейти к целым числам

 cut(control_vs_fast$reflection, c(-Inf, 0, 3, Inf), labels = FALSE)
# [1] 1 1 2 2 2 3 3
 

или определить наши собственные метки

 cut(control_vs_fast$reflection, c(-Inf, 0, 3, Inf), labels = c("no", "low", "high"))
# [1] no   no   low  low  low  high high
# Levels: no low high
as.character(cut(control_vs_fast$reflection, c(-Inf, 0, 3, Inf), labels = c("no", "low", "high")))
# [1] "no"   "no"   "low"  "low"  "low"  "high" "high"
 

Обратите внимание, что когда labels=FALSE все возвращаемые значения являются целыми числами, в противном случае они равны factor s. Если вам нужны строки (и / или вы не знаете, что factor такое s), то последний с as.character дает вам строки.

Исправление

Но все вышеперечисленное неправильно помечено 0 как "no" вместо "less" . Чтобы обойти это, вот немного более длинная альтернатива. Если вы используете целочисленный вариант, простое переназначение работает как есть; но если вам нужны строки, тогда factor s будет представлять небольшую проблему; Я буду использовать as.character вариант здесь.

 control_vs_fast$refsplit <- as.character(cut(control_vs_fast$reflection, c(0, 3, Inf), labels = c("low", "high"), include.lowest = TRUE))
control_vs_fast
#   reflection refsplit
# 1         -1     <NA>
# 2          0      low
# 3          1      low
# 4          2      low
# 5          3      low
# 6          4     high
# 7          5     high
control_vs_fast$refsplit[is.na(control_vs_fast$refsplit)] <- "no"
control_vs_fast
#   reflection refsplit
# 1         -1       no
# 2          0      low
# 3          1      low
# 4          2      low
# 5          3      low
# 6          4     high
# 7          5     high
 

Объяснение:

Проблема в том, что диапазоны в cut являются либо открытыми слева (по умолчанию), либо открытыми справа. Единственный способ получить одну из ячеек, как закрытую слева, так и закрытую справа, — это сделать ее первым диапазоном / ячейкой и добавить include.lowest=TRUE . Отсюда будет все, что меньше 0 (если оно у вас есть) NA , что означает, что оно не было ни в одном из назначенных ячеек.

Оттуда мы используем индексированное присваивание на основе тех, которые есть NA .

Ответ №2:

Возможно, вы можете попробовать приведенный ниже код

 within(
  control_vs_fast,
  refsplit <- c("high","low")[(reflection <=3) 1]
)
 

или

 within(
  control_vs_fast,
  refsplit <- ifelse(reflection <=3,"low","high")
)
 

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

1. Привет, большое спасибо за это. Я пытаюсь понять оба отправленных вами кода. Итак, я думаю, что понимаю второе. Если что-либо равно 3 и ниже, оно классифицируется как низкое, а все, что выше, является высоким. Я просто пытаюсь понять первый код.

2. @dquestions Да, вы поняли!

Ответ №3:

Вот пример с воспроизводимыми данными:

 set.seed(1)
x <- sample(0:7, size = 10, replace = TRUE)

ifelse(x <= 3, 'low', "high")

#  [1] "low"  "low"  "high" "low"  "low"  "high" "high" "low"  "high"
# [10] "low"