从多个字符(字符串)变量创建虚拟变量(r)

时间:2017-06-14 16:57:57

标签: r

我需要从字符(字符串)变量创建一个虚拟变量(二进制) 我看起来像这样的数据:

dat <- tribble(
    ~pat_id, ~icd9_1, ~icd9_2,
    1, "414.01", "414.01",
    2, "411.89", NA,
    3, NA, "410.71",
    4, NA, NA,
    5, NA, "410.51",
    6, NA, "272.0, 410.71"
)
dat



# A tibble: 6 x 3
#         pat_id icd9_1        icd9_2
#          <dbl>  <chr>         <chr>
#              1 414.01        414.01
#              2 411.89          <NA>
#              3   <NA>        410.71
#              4   <NA>          <NA>
#              5   <NA>        410.51
#              6   <NA> 272.0, 410.71

我想创建三个新的二进制变量:

对于icd9_bin_1

icd9_1 ==二进制(0/1) icd9_bin_2的{​​{1}} ==二进制(0/1)
对于icd9_2icd9_bin

icd9_1 ==二进制

创建这些二进制变量的最快方法是什么?

我已将icd9_2替换为NA,转换为一个因素然后重新编码,但是 永远。

0

我正在寻找更优雅的解决方案。想法?

2 个答案:

答案 0 :(得分:1)

要手动创建二进制值,只需将函数应用于每个列,然后使用列的or找到两个都不是NA的行。

is_not_na <- function(...) Negate(is.na)(...)

dat %>%
  mutate(icd9_bin_1 = icd9_1 %>% is_not_na() %>% as.numeric(),
         icd9_bin_2 = icd9_2 %>% is_not_na() %>% as.numeric(),
         icd9_bin = as.numeric(icd9_bin_1 | icd9_bin_2))
#> # A tibble: 6 x 6
#>   pat_id icd9_1        icd9_2 icd9_bin_1 icd9_bin_2 icd9_bin
#>    <dbl>  <chr>         <chr>      <dbl>      <dbl>    <dbl>
#> 1      1 414.01        414.01          1          1        1
#> 2      2 411.89          <NA>          1          0        1
#> 3      3   <NA>        410.71          0          1        1
#> 4      4   <NA>          <NA>          0          0        0
#> 5      5   <NA>        410.51          0          1        1
#> 6      6   <NA> 272.0, 410.71          0          1        1

如果您有许多这样的列,则可以使用mutate_at()

is_not_na_num <- function(...) as.numeric(Negate(is.na)(...))

# Make up a new column
dat$icd9_3 <- rev(dat$icd9_1)

# To use pattern matching...
data_auto <- dat %>%
  mutate_at(vars(matches("icd9")), funs(bin = is_not_na_num))
data_auto
#> # A tibble: 6 x 7
#>   pat_id icd9_1        icd9_2 icd9_3 icd9_1_bin icd9_2_bin icd9_3_bin
#>    <dbl>  <chr>         <chr>  <chr>      <dbl>      <dbl>      <dbl>
#> 1      1 414.01        414.01   <NA>          1          1          0
#> 2      2 411.89          <NA>   <NA>          1          0          0
#> 3      3   <NA>        410.71   <NA>          0          1          0
#> 4      4   <NA>          <NA>   <NA>          0          0          0
#> 5      5   <NA>        410.51 411.89          0          1          1
#> 6      6   <NA> 272.0, 410.71 414.01          0          1          1

(但要自动化最终or,您可以使用reduce() ...)

bin_any <- data_auto %>%
  select(matches("_bin")) %>%
  purrr::reduce(~ as.numeric(.x | .y))
data_auto$icd9_bin <- bin_any
data_auto["icd9_bin"]
#> # A tibble: 6 x 1
#>   icd9_bin
#>      <dbl>
#> 1        1
#> 2        1
#> 3        1
#> 4        0
#> 5        1
#> 6        1

答案 1 :(得分:0)

根据您的意见,if_else()是一个dplyr功能,如果符合您的要求,则与mutate()配合使用:

dat <- dat %>%
  mutate(icd9_bin_1 = if_else(is.na(dat$icd9_1), "no icd9 dx", "icd9"),
         more...)