У вас все не так. Вам нужно heart_conditions %in% "hypertension"
(или heart_conditions == "hyptertension"
)!
Или полный ответ:
hypertension.df$hypertension <- ifelse(heart_conditions == "hypertension" | bp_med == 1, 1, 2)
# or using %in%
selection <- "hypertension"
hypertension.df$hypertension <- ifelse(heart_conditions %in% selection | bp_med == 1, 1, 2)
Более длинное объяснение
%in%
проверяет, если левый- hand-side присутствует в правой части и возвращает объект длины левой стороны.
names <- c("Alice", "Bob", "Charlie")
names %in% c("Alice", "Charlie")
#> [1] TRUE FALSE TRUE
"Alice" %in% names
#> [1] TRUE
Создано 06.08.2020 пакет репекс (v0.3.0)
Частичное совпадение
Как упоминалось в комментариях: %in%
полностью сравнивает элементы. Чтобы проверить, находится ли строка внутри другой строки, мы можем сделать следующее:
Сравнение строк
library(tibble) # data.frames
df <- tribble(
~heart_conditions, ~high_chol_tabs, ~bp_med, ~hypertension,
"hypertension high_cholesterol", 2, 2, 1,
"none", 4, 4, 1,
"hypertension high_cholesterol", 1, 1, 1,
"heart_attack angina", 4, 4, 1,
"high_cholesterol", 2, 4, 1,
"hypertension high_cholesterol", 1, 1, 1,
"none", 4, 4, 1,
"none", 4, 4, 1,
"high_cholesterol", 2, 4, 1,
"hypertension high_cholesterol", 1, 1, 1
)
df$hypertension1 <- ifelse(grepl("hypertension", df$heart_conditions) | df$bp_med == 1, 1, 2)
library(stringr)
# imho more user friendly than grepl, but slightly slower
df$hypertension2 <- ifelse(str_detect(df$heart_conditions, "hypertension") | df$bp_med == 1, 1, 2)
df
#> # A tibble: 10 x 6
#> heart_conditions high_chol_tabs bp_med hypertension hypertension1
#> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 hypertension hi… 2 2 1 1
#> 2 none 4 4 1 2
#> 3 hypertension hi… 1 1 1 1
#> 4 heart_attack an… 4 4 1 2
#> 5 high_cholesterol 2 4 1 2
#> 6 hypertension hi… 1 1 1 1
#> 7 none 4 4 1 2
#> 8 none 4 4 1 2
#> 9 high_cholesterol 2 4 1 2
#> 10 hypertension hi… 1 1 1 1
#> # … with 1 more variable: hypertension2 <dbl>
Создано 06.08.2020 пакетом REPEX (v0.3.0)
Разделить и сравнить
Немного более медленное решение, которое не полагается на сравнение строк, состоит в том, чтобы разделить условия по пробелу и проверить, есть ли они являются гипертонией, вы можете сделать это так:
# split the heart-conditions
conds <- strsplit(df$heart_conditions, " ")
conds
#> [[1]]
#> [1] "hypertension" "high_cholesterol"
#>
#> [[2]]
#> [1] "none"
#>
#> [[3]]
#> [1] "hypertension" "high_cholesterol"
#>
#> [[4]]
#> [1] "heart_attack" "angina"
#>
#> [[5]]
#> [1] "high_cholesterol"
#>
#> [[6]]
#> [1] "hypertension" "high_cholesterol"
#>
#> [[7]]
#> [1] "none"
#>
#> [[8]]
#> [1] "none"
#>
#> [[9]]
#> [1] "high_cholesterol"
#>
#> [[10]]
#> [1] "hypertension" "high_cholesterol"
# for each row of the data, check if any value is hypertension
has_hypertension <- sapply(conds, function(cc) any(cc == "hypertension"))
has_hypertension
#> [1] TRUE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE TRUE
df$hypertension3 <- ifelse(has_hypertension | df$bp_med == 1, 1, 2)
df
#> # A tibble: 10 x 7
#> heart_conditions high_chol_tabs bp_med hypertension hypertension1
#> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 hypertension hi… 2 2 1 1
#> 2 none 4 4 1 2
#> 3 hypertension hi… 1 1 1 1
#> 4 heart_attack an… 4 4 1 2
#> 5 high_cholesterol 2 4 1 2
#> 6 hypertension hi… 1 1 1 1
#> 7 none 4 4 1 2
#> 8 none 4 4 1 2
#> 9 high_cholesterol 2 4 1 2
#> 10 hypertension hi… 1 1 1 1
#> # … with 2 more variables: hypertension2 <dbl>, hypertension3 <dbl>
Создано 06.08.2020 с помощью пакета реплекс (v0.3.0)
Бенчмарк
Заинтригованный моими предыдущими комментариями, я провел быстрый тест, сравнивая различные решения, а также добавил решение, используя stringi
:
# splitter function
has_hypertension <- function(x) sapply(strsplit(x, " "), function(cc) any(cc == "hypertension"))
# create a larger dataset
df_large <- df %>% slice(rep(1:n(), 10000))
# benchmark the code:
bench::mark(
grepl = grepl("hypertension", df_large$heart_conditions),
stringi = stringi::stri_detect(df_large$heart_conditions, fixed = "hypertension"),
stringr = str_detect(df_large$heart_conditions, "hypertension"),
splitter = has_hypertension(df_large$heart_conditions)
)
#> # A tibble: 4 x 13
#> expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result memory time gc
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> #> <bch:tm> <list> <list> <list> <list>
#> 1 grepl 16.67ms 16.91ms 59.0 390.67KB 2.11 28 1 474ms <lgl [100,00… <Rprofmem[,3] [1 × … <bch:tm [2… <tibble [29 ×…
#> 2 stringi 2.68ms 2.93ms 344. 390.67KB 6.22 166 3 482ms <lgl [100,00… <Rprofmem[,3] [1 × … <bch:tm [1… <tibble [169 …
#> 3 stringr 17.74ms 17.96ms 55.1 390.67KB 0 28 0 508ms <lgl [100,00… <Rprofmem[,3] [1 × … <bch:tm [2… <tibble [28 ×…
#> 4 splitter 153.39ms 153.39ms 6.52 3.67MB 19.6 1 3 153ms <lgl [100,00… <Rprofmem[,3] [551 … <bch:tm [4… <tibble [4 × …
Что ясно показывает, что stringi::stri_detect(txt, fixed = "hypertension")
безусловно, самый быстрый!