Как добавить столбец в фрейм данных на основе условия?

Например, у меня есть следующий фрейм данных. Я хочу добавить еще один столбец (7-й столбец) в этот фрейм данных.

Условие - if Sepal.Length >=5 assign "UP" else assign "DOWN". Мы бы назвали этот столбец "Регулирование".

 > iris 
     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
    1            5.1         3.5          1.4         0.2     setosa
    2            4.9         3.0          1.4         0.2     setosa
    3            4.7         3.2          1.3         0.2     setosa
    4            4.6         3.1          1.5         0.2     setosa
    5            5.0         3.6          1.4         0.2     setosa
    6            5.4         3.9          1.7         0.4     setosa
    7            4.6         3.4          1.4         0.3     setosa
    8            5.0         3.4          1.5         0.2     setosa
    9            4.4         2.9          1.4         0.2     setosa
    10           4.9         3.1          1.5         0.1     setosa
    ...

Какой способ сделать это?

Ответ 1

Try

iris$Regulation <- ifelse(iris$Sepal.Length >=5, "UP", "DOWN")

Ответ 2

В интересах обновления возможного канонического пакета dplyr имеет функцию mutate которая позволяет создавать новый столбец в data.frame в векторизованном виде:

library(dplyr)
iris_new <- iris %>%
    mutate(Regulation = if_else(Sepal.Length >= 5, 'UP', 'DOWN'))

Это создает новый столбец с названием " Regulation который состоит из 'UP' или 'DOWN' зависимости от применения условия к столбцу Sepal.Length.

Функция case_when (также из dplyr) обеспечивает легкий для чтения способ dplyr воедино несколько условий:

iris %>%
    mutate(Regulation = case_when(Sepal.Length >= 5 ~ 'High',
                                  Sepal.Length >= 4.5 ~ 'Mid',
                                  TRUE ~ 'Low'))

Это работает так же, как if_else за исключением того, что вместо 1 условия с возвращаемым значением для TRUE и FALSE, каждая строка имеет условие (слева от ~) и возвращаемое значение (справа от ~), которое она возвращает, если TRUE. Если false, он переходит к следующему условию.

В этом случае строки, в которых Sepal.Length >= 5 вернет значение 'High', строки, в которых Sepal.Length < 5 (поскольку первое условие должно было быть не выполнено) и Sepal.Length >= 4.5, вернут значение 'Mid', а все остальные строки будут возвращать 'Low'. Поскольку TRUE всегда TRUE, он используется для предоставления значения по умолчанию.

Ответ 3

Без ifelse:

iris$Regulation <- c("DOWN", "UP")[ (iris$Sepal.Length >= 5) + 1 ]

Тест, примерно в 14 раз быстрее, чем ifelse:

bigX <- runif(10^6, 0, 10)

bench::mark(
  x1 = c("DOWN", "UP")[ (bigX >= 5) + 1 ],
  x2 = ifelse(bigX >=5, "UP", "DOWN"),
  x3 = dplyr::if_else(bigX >= 5, "UP", "DOWN")
)
# # A tibble: 3 x 14
# expression     min    mean  median     max 'itr/sec' mem_alloc  n_gc n_itr total_time result memory
# <chr>      <bch:t> <bch:t> <bch:t> <bch:t>     <dbl> <bch:byt> <dbl> <int>   <bch:tm> <list> <list>
# x1          19.1ms  23.9ms  20.5ms  31.6ms     41.9     22.9MB     9    22      525ms <chr ~ <Rpro~
# x2         278.9ms 280.2ms 280.2ms 281.5ms      3.57   118.3MB     4     2      560ms <chr ~ <Rpro~
# x3          47.8ms  64.2ms  54.1ms 138.8ms     15.6     68.7MB    11     8      514ms <chr ~ <Rpro~