【问题标题】:Dummy variable creation for each subcategory using tidyverse package使用 tidyverse 包为每个子类别创建虚拟变量
【发布时间】:2020-06-18 19:23:24
【问题描述】:

我有一个 tibble(引用自 How to create dummy variables per group of another variable in tidyverse

library(tidyverse)

input_data <- tribble( ~Subcat, ~Date, ~COMM1,~COMM2,~UOM,~AUC_TYPE,
                        #--|----------|-----|-----|----|----------------|
                        1, 2017-03-07, 40750,41400,"MT","English",
                        1, 2017-03-15, 40750,40000,"MT","English",

                        2, 2017-10-16, 41000,40500,"METER","Yankee",
                        2, 2017-11-06, 41010,40510,"METER","Yankee",
                        2, 2019-01-26, 50010,50510,"METER","English",

                        3, 2017-03-07, 40750,41400,"MT","English",
                        3, 2018-05-26, 50010,50510,"MT","English",
                        3, 2019-01-21, 40750,40200,"MT","English",
                        3, 2019-01-21, 40750,40200,"MT","English",

                        4, 2017-11-08, 37500,39000,"LTR","Dynamic Sealbid",
                        4, 2017-11-08, 37500,39000,"LTR","Dynamic Sealbid",
)

期望的输出

output_data <- tribble( ~Subcat, ~Date, ~COMM1, ~COMM2, ~UOM_MT, ~UOM_METER ,~UOM_LTR, ~AUC_TYPE_English, ~`AUC_TYPE_Dynamic Sealbid`, ~AUC_TYPE_Yankee,
                        #--|----------|-----|-----|-|-|-|-|-|-|
                        1, 2017-03-07, 40750,41400,1,0,0,1,0,0,
                        1, 2017-03-15, 40750,40000,1,0,0,1,0,0,

                        2, 2017-10-16, 41000,40500,0,1,0,0,0,1,
                        2, 2017-11-06, 41010,40510,0,1,0,0,0,1,
                        2, 2019-01-26, 50010,50510,0,1,0,1,0,0,

                        3, 2017-03-07, 40750,41400,1,0,0,1,0,0,
                        3, 2018-05-26, 50010,50510,1,0,0,1,0,0,
                        3, 2019-01-21, 40750,40200,1,0,0,1,0,0,
                        3, 2019-01-21, 40750,40200,1,0,0,1,0,0,

                        4, 2017-11-08, 37500,39000,0,0,1,0,1,0,
                        4, 2017-11-08, 37500,39000,0,0,1,0,1,0,
)

【问题讨论】:

  • 虽然有一个公认的答案,你仍然可以参考我的。它使用了不同的概念。

标签: r tidyverse dummy-variable


【解决方案1】:

你可以这样做:

library(dplyr)
library(tidyr)

input_data %>%
   #Get unique row number
   mutate(row = row_number()) %>%
   #Get data in long format
   pivot_longer(cols = c(UOM, AUC_TYPE)) %>%
   #Combine columns
   unite(col, name, value) %>%
   #Get data in wide format
   pivot_wider(names_from = col, values_from = col, values_fn = list(col = ~1), 
               values_fill = list(col = 0)) %>%
   #Remove row column
   select(-row)


# A tibble: 11 x 10
#   Subcat  Date COMM1 COMM2 UOM_MT AUC_TYPE_English UOM_METER AUC_TYPE_Yankee UOM_LTR `AUC_TYPE_Dynamic Sealbid`
#    <dbl> <dbl> <dbl> <dbl>  <dbl>            <dbl>     <dbl>           <dbl>   <dbl>                      <dbl>
# 1      1  2007 40750 41400      1                1         0               0       0                          0
# 2      1  1999 40750 40000      1                1         0               0       0                          0
# 3      2  1991 41000 40500      0                0         1               1       0                          0
# 4      2  2000 41010 40510      0                0         1               1       0                          0
# 5      2  1992 50010 50510      0                1         1               0       0                          0
# 6      3  2007 40750 41400      1                1         0               0       0                          0
# 7      3  1987 50010 50510      1                1         0               0       0                          0
# 8      3  1997 40750 40200      1                1         0               0       0                          0
# 9      3  1997 40750 40200      1                1         0               0       0                          0
#10      4  1998 37500 39000      0                0         0               0       1                          1
#11      4  1998 37500 39000      0                0         0               0       1                          1

【讨论】:

  • 您的结果与 OP 想要的结果不同。您没有使用正确的唯一标识符。
  • @DarrenTsai 您能具体告诉我哪一行的输出与 OP 的输出不匹配吗?请注意,我的输出和 OP 中的列顺序是不同的。
【解决方案2】:

该方法使用C()contrasts()设置因子变量的对比矩阵,并调用model.matrix()将这些因子变量转换为哑元。

请注意,如果一个因子变量有 k 个级别,model.matrix() 默认会创建 k-1 个虚拟变量。所以这里我通过C()contrasts()来调整这个属性。

library(dplyr)
library(tibble)

df %>%
  select("UOM_" = UOM, "AUC_TYPE_" = AUC_TYPE) %>%  # select and rename
  mutate_all(as.factor) %>%
  mutate_all(~ C(., contrasts(., contrasts = F), how.many = n_distinct(.))) %>%
  model.matrix(~ ., data = .) %>%
  as_tibble %>%
  select(-`(Intercept)`) %>%
  bind_cols(select(df, -c(UOM, AUC_TYPE)), .)

# # A tibble: 11 x 10
#    Subcat  Date COMM1 COMM2 UOM_LTR UOM_METER UOM_MT `AUC_TYPE_Dynamic Sealbid` AUC_TYPE_English AUC_TYPE_Yankee
#     <dbl> <dbl> <dbl> <dbl>   <dbl>     <dbl>  <dbl>                      <dbl>            <dbl>           <dbl>
#  1      1  2007 40750 41400       0         0      1                          0                1               0
#  2      1  1999 40750 40000       0         0      1                          0                1               0
#  3      2  1991 41000 40500       0         1      0                          0                0               1
#  4      2  2000 41010 40510       0         1      0                          0                0               1
#  5      2  1992 50010 50510       0         1      0                          0                1               0
#  6      3  2007 40750 41400       0         0      1                          0                1               0
#  7      3  1987 50010 50510       0         0      1                          0                1               0
#  8      3  1997 40750 40200       0         0      1                          0                1               0
#  9      3  1997 40750 40200       0         0      1                          0                1               0
# 10      4  1998 37500 39000       1         0      0                          1                0               0
# 11      4  1998 37500 39000       1         0      0                          1                0               0

【讨论】:

    猜你喜欢
    • 2019-11-09
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    相关资源
    最近更新 更多