[英]Do I leave features with numeric categories as it is or create dummy variables?
[英]I am searching an optimal way to change variable categories in dummy variables
我有一些患者在不同的時間接受不同的治療。 我想將他們接受的治療更改為二進制變量,如果患者至少接受過一次葯物,則取值為 1,如果他們從未接受過葯物,則取值為 0。
我設法做到了這一點,但是以一種乏味的方式,這對於數十種不同類型的葯物來說可能很困難。
我想優化我的代碼,主要是避免一一創建與葯物相關的所有二進制變量。
id<-c(rep(1,7),rep(2,4))
medoc<-c("par","mor","mor","par","sed","sed",
"sed","cur","sed","cur","sed")
mydata<-data.frame(id,medoc)
mydata2<-mydata%>%group_by(id)%>%
mutate(medoc_str=paste(unique(medoc),collapse = " "))%>%
distinct(id,.keep_all = TRUE)
mydata2$par<-NA
mydata2$mor<-NA
mydata2$sed<-NA
mydata2$cur<-NA
mydata2$par<-ifelse(
grepl("par",mydata2$medoc_str)==TRUE,1,0
)
mydata2$mor<-ifelse(
grepl("mor",mydata2$medoc_str)==TRUE,1,0
)
mydata2$sed<-ifelse(
grepl("sed",mydata2$medoc_str)==TRUE,1,0
)
mydata2$cur<-ifelse(
grepl("cur",mydata2$medoc_str)==TRUE,1,0
)
如果我理解它,你想使你的變量變得愚蠢。 我們也可以使用tidyr::pivot_wider
來做到這一點,但我真的很喜歡使用特定的庫來輕松地做到這一點。 我喜歡fastDummies
package:
library(fastDummies)
dummy_cols(mydata, select_columns = 'medoc')
id medoc medoc_cur medoc_mor medoc_par medoc_sed
1 1 par 0 0 1 0
2 1 mor 0 1 0 0
3 1 mor 0 1 0 0
4 1 par 0 0 1 0
5 1 sed 0 0 0 1
6 1 sed 0 0 0 1
7 1 sed 0 0 0 1
8 2 cur 1 0 0 0
9 2 sed 0 0 0 1
10 2 cur 1 0 0 0
11 2 sed 0 0 0 1
這是pivot_wider
的答案:
library(tidyr)
library(dplyr)
mydata %>% mutate(index = row_number()) %>%
pivot_wider(names_from = medoc,
values_from = medoc,
values_fn = \(x) +!is.na(x),
values_fill = 0)
與@Guedes 類似但具有不同values_fn
的解決方案:
library(dplyr)
library(tidyr)
mydata %>%
mutate(row = row_number()) %>%
pivot_wider(names_from = medoc, values_from = medoc,
values_fn = function(x) 1, values_fill = 0) %>%
select(-row)
# A tibble: 11 x 5
id par mor sed cur
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 0 0 0
2 1 0 1 0 0
3 1 0 1 0 0
4 1 1 0 0 0
5 1 0 0 1 0
6 1 0 0 1 0
7 1 0 0 1 0
8 2 0 0 0 1
9 2 0 0 1 0
10 2 0 0 0 1
11 2 0 0 1 0
假設您希望每個 id 有一行,其中二進制列指示 medoc 的哪些值存在 (1) 或不存在 (0),我們可以使用這樣的表。 (如果您想要計數而不是存在/不存在,則省略 pmin。)
pmin(table(mydata), 1)
## medoc
## id cur mor par sed
## 1 0 1 1 1
## 2 1 0 0 1
或作為數據框並添加 medoc_str
library(dplyr)
library(tibble)
mydata %>%
table %>%
pmin(1) %>%
as.data.frame.matrix %>%
rowwise %>%
mutate(medoc_str = paste(names(.)[c_across() == 1], collapse = " ")) %>%
ungroup %>%
rownames_to_column(var = "id")
## # A tibble: 2 x 6
## id cur mor par sed medoc_str
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 1 0 1 1 1 mor par sed
## 2 2 1 0 0 1 cur sed
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.