Существует очень классный пакет для такого перевода, называемый dtplyr
:
library(dplyr)
library(dtplyr)
library(data.table)
Единственное изменение, которое вы должны внести в свой исходный код, - это обернуть ваш объект в lazy_dt
перед тем, как запустив команду:
lazy_dt(ipoi_pdi) %>%
group_by(
id
) %>%
mutate(
tipo_servico = case_when(
n() == 1 ~ tipo_servico,
n() > 1 & any(tipo_servico == "IFR - 6 horas") ~ "IFR - 6 horas",
n() > 1 & any(tipo_servico == "IFR - 12 horas") ~ "IFR - 12 horas",
TRUE ~ "Não é IFR"
)
) -> ipoi_pdi
Теперь, когда вы печатаете объект, он отображает соответствующий код data.table
как Call
:
print(ipoi_pdi)
#> Source: local data table [?? x 2]
#> Call: copy(`_DT1`)[, `:=`(tipo_servico = case_when(.N == 1 ~ tipo_servico,
#> .N > 1 & any(tipo_servico == "IFR - 6 horas") ~ "IFR - 6 horas",
#> .N > 1 & any(tipo_servico == "IFR - 12 horas") ~ "IFR - 12 horas",
#> TRUE ~ "Não é IFR")), keyby = .(id)]
#>
#> id tipo_servico
#> <chr> <chr>
#> 1 1 IFR - 6 horas
#> 2 1 IFR - 6 horas
#> 3 2 Convocação
#> 4 3 Escala Normal
#> 5 4 Não é IFR
#> 6 4 Não é IFR
#>
#> # Use as.data.table()/as.data.frame()/as_tibble() to access results
Преобразуйте ваш объект в data.table
и выполните вызов:
ipoi_pdi_dt <- as.data.table(ipoi_pdi)
ipoi_pdi_dt_new <- ipoi_pdi_dt[, `:=`(tipo_servico = case_when(.N == 1 ~ tipo_servico,
.N > 1 & any(tipo_servico == "IFR - 6 horas") ~ "IFR - 6 horas",
.N > 1 & any(tipo_servico == "IFR - 12 horas") ~ "IFR - 12 horas",
TRUE ~ "Não é IFR")), keyby = .(id)]
print(ipoi_pdi_dt_new)
#> id tipo_servico
#> 1: 1 IFR - 6 horas
#> 2: 1 IFR - 6 horas
#> 3: 2 Convocação
#> 4: 3 Escala Normal
#> 5: 4 Não é IFR
#> 6: 4 Não é IFR
Чтобы проверить, равны ли результаты:
all.equal(as.data.frame(ipoi_pdi_new), as.data.frame(ipoi_pdi_dt_new))
#> [1] TRUE
Поскольку data.table
не имеет эквивалента case_when
, эта часть остается той же. Если вы делаете это по соображениям производительности, это должно быть хорошо. В противном случае вы должны использовать кучу ifelse
вызовов для его замены.