Я пытаюсь вернуть меньшую из двух значений, но он смотрит на весь столбец данных [повтор].

Вопрос или проблема

Я хочу, чтобы моя переменная ttA была меньшей из TIME_TO_A и TIME_TO_B. Но этот код, похоже, рассматривает целые столбцы, а не только значение для каждой отдельной строки. В данный момент, каждый раз, когда TIME_TO_A <= 183, он возвращает 0.

data6mo <- data %>%
   mutate(ttA = 
case_when( 
    TIME_TO_A > 183 ~ 183, 
    TIME_TO_A <= 183 ~ min(TIME_TO_A, TIME_TO_B, na.rm = TRUE)
         ))

Используйте функцию pmin()

library(dplyr)

data <- data.frame(
  time_to_a = c(100, 130, 185, 200),
  time_to_b = c(70, 160, 185, 200)
)

data
#>   time_to_a time_to_b
#> 1       100        70
#> 2       130       160
#> 3       185       185
#> 4       200       200

data6mo <- data %>%
  mutate(
    ttA = case_when(
      time_to_a > 183 ~ 183,
      time_to_a <= 183 ~ pmin(time_to_a, time_to_b, na.rm = TRUE)
    )
  )

data6mo
#>   time_to_a time_to_b ttA
#> 1       100        70  70
#> 2       130       160 130
#> 3       185       185 183
#> 4       200       200 183

Создано 2024-10-22 с помощью reprex v2.0.2

В базовом R:

 transform(data, a = pmin(time_to_a, time_to_b, 183))

  time_to_a time_to_b   a
1       100        70  70
2       130       160 130
3       185       185 183
4       200       200 183

Согласно логике в вашей попытке кода, я думаю, что ifelse + pmin должны хорошо сработать

(Обратите внимание, смотрите фиктивные данные в пятой строке, что является краевым случаем, упомянутым в комментарии @Johan Rosa к @решению Onyambu)

> transform(data, ttA = ifelse(time_to_a > 183, 183, pmin(time_to_a, time_to_b)))
  time_to_a time_to_b ttA
1       100        70  70
2       130       160 130
3       185       185 183
4       200       200 183
5       185        70 183

или один из его вариантов, например,

> transform(data, ttA = 183 * (time_to_a > 183) + pmin(time_to_a, time_to_b) * (time_to_a <= 183))
  time_to_a time_to_b ttA
1       100        70  70
2       130       160 130
3       185       185 183
4       200       200 183
5       185        70 183

Данные

data <- data.frame(
    time_to_a = c(100, 130, 185, 200, 185),
    time_to_b = c(70, 160, 185, 200, 70)
)

.

Ответ или решение

Как правильно вернуть минимальное значение из двух переменных в R

Ситуация, с которой вы столкнулись, касается определения минимального значения между двумя переменными TIME_TO_A и TIME_TO_B в строки данных, при этом необходимо учитывать условие: если TIME_TO_A превышает 183, возвращать 183. Ваша начальная попытка с использованием функции min использует весь столбец, вместо того чтобы смотреть на отдельные строки. Это распространённая проблема, которая может возникнуть при работе с колоночными операциями в dplyr.

Подход с использованием pmin()

Наиболее эффективный и простой способ решения вашей задачи — использовать функцию pmin(), которая возвращает поэлементное минимальное значение из нескольких векторов. Функция pmin() позволяет значительно упростить вашу логику и сделать код более читаемым.

Вот пример кода, который вы можете использовать:

library(dplyr)

data <- data.frame(
  time_to_a = c(100, 130, 185, 200),
  time_to_b = c(70, 160, 185, 200)
)

data6mo <- data %>%
  mutate(
    ttA = case_when(
      time_to_a > 183 ~ 183,
      TRUE ~ pmin(time_to_a, time_to_b, na.rm = TRUE)
    )
  )

print(data6mo)

Ожидаемый результат

При выполнении этого кода вы получите следующий вывод:

  time_to_a time_to_b ttA
1       100        70  70
2       130       160 130
3       185       185 183
4       200       200 183

Этот подход работает следующим образом:

  • Если time_to_a больше 183, то возвращается фиксированное значение 183.
  • Если же time_to_a меньше или равно 183, используется pmin для расчета минимального значения между time_to_a и time_to_b.

Альтернативные методы

Вы также можете решить эту задачу с использованием базового R или комбинации ifelse и pmin. Вот пример с использованием ifelse:

data6mo <- transform(data, ttA = ifelse(time_to_a > 183, 183, pmin(time_to_a, time_to_b, na.rm = TRUE)))

Или путем комбинирования логических условий:

data6mo <- transform(data, ttA = 183 * (time_to_a > 183) + pmin(time_to_a, time_to_b) * (time_to_a <= 183))

Заключение

Использование pmin()— это простой, понятный и эффективный способ вернуть минимальное значение между двумя переменными для каждой строки, предоставляя вам необходимую гибкость в обработке условий. Убедитесь, что вы подключили пакет dplyr, чтобы использовать такие функции, и всегда проверяйте ваши данные на наличие пропусков, чтобы избежать неожиданных результатов.

Если у вас остались вопросы или есть необходимость в более глубоком разборе, не стесняйтесь задавать их!

Оцените материал
Добавить комментарий

Капча загружается...