【问题标题】:Creating group dummy variable创建组虚拟变量
【发布时间】:2020-01-31 18:51:18
【问题描述】:

我有一个看起来像这样的大数据框

   A  B   Q3    Q40   Q41   C
1  *  *   1     NA    NA   *
2  *  *   NA    NA    1    *
3  *  *   NA    1     NA   * 
4  *  *   NA    NA    1    *
5  *  *   1     NA    NA   *

我想创建一个虚拟变量来指示由 Q3、Q40 和 Q41 指定的组。最后我希望输出看起来像

   A  B   Q3    Q40   Q41   C   Group
1  *  *   1     NA    NA   *   Group1
2  *  *   NA    NA    1    *   Group3
3  *  *   NA    1     NA   *   Group2
4  *  *   NA    NA    1    *   Group3
5  *  *   1     NA    NA   *   Group1

我无法弄清楚如何创建这个虚拟变量“组”。我是把它写成单独的函数,如下所示,还是有更简单的方法?

dummy<- function (df$V1){
if (df$V1==1)
   return ("Group1")

非常感谢任何想法!

【问题讨论】:

    标签: r function dataframe dummy-variable


    【解决方案1】:

    一种可能性是使用 apply 并逐行检查 V1 到 V3 中哪个等于 1:

    variables <- c("Q3", "Q40", "Q41")
    # Works only for exactly one '1' per row:
    # my_df$Group <- apply(my_df[variables], 1, function(x) which(x == 1))
    # Works for multiple '1' per row or rows without '1': 
    my_df$Group <- apply(my_df[, variables], 1, function(x) paste(which(x %in% 1), collapse = "_"))
    my_df$Group <- paste0("Group", my_df$Group)
    my_df
    #   A B Q3 Q40 Q41 C    Group
    # 1 * *  1  NA  NA *   Group1
    # 2 * * NA  NA   1 *   Group3
    # 3 * * NA   1  NA *   Group2
    # 4 * * NA  NA   1 *   Group3
    # 5 * *  1  NA   1 * Group1_3
    

    数据

    my_df <- read.table(text ="      A  B   Q3    Q40   Q41   C   Group
    1  *  *   1     NA    NA   *   Group1
    2  *  *   NA    NA    1    *   Group3
    3  *  *   NA    1     NA   *   Group2
    4  *  *   NA    NA    1    *   Group3
    5  *  *   1     NA    1   *   Group1", header = TRUE)
    

    【讨论】:

    • 非常感谢!我检查 my_df$Group 时的输出类似于 "Groupc(V1 = 1)" "Groupc(V5 = 5)" "Groupc(V2 = 2)" "Groupc(V2 = 2)。如何更改标签,使其只是“第 1 组”、“第 2 组”等?
    • 嗯,看起来apply返回的结果不是一个数字,而是Q3 = 1之类的东西。你确定你用的是==?也许您可以调整您的示例以更好地匹配您的原始数据框。
    • 刚刚更新了示例以匹配我在数据集中的实际列标签
    • 我认为这可能是由于您的行中有多个等于 1 的列?虽然我对你的数字 5 和 2 感到困惑......这对我来说是不可重现的,但我编辑了我的答案以解释更多列可能等于 1 的事实。
    • 我没有多于一列的行。对于每个观察值 1:5,Q3 或 Q40 或 Q41 为 1,互斥。当我运行df$Group &lt;- apply(df[, 29:31], 1, function(x) which(x == 1)) df$Group &lt;- paste0("Group ", df$Group)(其中 29:31 是 Q3、Q40、Q41 列的位置)然后我检查 df$Group 的前五个结果时,我得到 ``` "Group integer(0)" "Group c( Q40 = 2)" "组c(Q3 = 1)" "组整数(0)" "组c(Q41 = 3) ``
    【解决方案2】:

    假设您在 V 列之前有 2 列,我们可以使用 max.col like

    paste0("Group", max.col(replace(df, is.na(df), 0) == 1) - 2)
    #[1] "Group1" "Group3" "Group2" "Group3" "Group1"
    

    如果中间列中有变量,我们可以将其子集化并使用max.col

    sub_df <- df[grep("^V", names(df))]
    paste0("Group", max.col(replace(sub_df, is.na(sub_df), 0) == 1))
    

    【讨论】:

    • 我总共有 150 个变量 - V1、V2、V3 位于中间
    • @IG114 更新了答案,这样无论这些变量在哪里,它都能正常工作。
    【解决方案3】:

    apply 的另一种快速用法:

    v1 <- c(1:3, NA, NA , NA)
    v2 <- c(NA, NA , NA, 1:3)
    df0 <- tibble::tibble(v1, v2)
    df0[["group"]] <- apply(df0, 1, function(x) names(x)[!is.na(x)])
    df0
    #> # A tibble: 6 x 3
    #>      v1    v2 group
    #>   <int> <int> <chr>
    #> 1     1    NA v1   
    #> 2     2    NA v1   
    #> 3     3    NA v1   
    #> 4    NA     1 v2   
    #> 5    NA     2 v2   
    #> 6    NA     3 v2
    

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 2017-08-01
      • 2018-04-06
      • 1970-01-01
      • 2016-12-12
      • 2017-02-24
      • 2012-09-27
      • 2023-03-14
      • 1970-01-01
      相关资源
      最近更新 更多