Ответ 1
Try
iris$Regulation <- ifelse(iris$Sepal.Length >=5, "UP", "DOWN")
Например, у меня есть следующий фрейм данных. Я хочу добавить еще один столбец (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
...
Какой способ сделать это?
Try
iris$Regulation <- ifelse(iris$Sepal.Length >=5, "UP", "DOWN")
В интересах обновления возможного канонического пакета 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
, он используется для предоставления значения по умолчанию.
Без 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~