【问题标题】:Create a new column based on true/false conditions of other columns根据其他列的真/假条件创建新列
【发布时间】:2021-08-05 13:45:20
【问题描述】:

我手动创建了这个数据框,但我想知道我可以编写什么代码来生成“名称”列,条件是:

如果 'dog' 为 TRUE,而 'blackfur' 和 'whitefur' 为 FALSE,则 name 等于 'no_dog'。

如果 'dog' 为 TRUE 且 'blackfur' 为 TRUE 且 'whitefur' 为 FALSE,则 name 等于 'black_dog'。

如果 'dog' 为 TRUE 且 'blackfur' 为 FALSE 且 'whitefur' 为 TRUE,则 name 等于 'white_dog'

ID  dog     blackfur    whitefur    name
1   TRUE    FALSE       FALSE       no_dog
2   TRUE    TRUE        FALSE       black_dog
3   TRUE    TRUE        FALSE       black_dog
4   TRUE    FALSE       TRUE        white_dog
5   TRUE    FALSE       TRUE        white_dog
6   TRUE    FALSE       TRUE        white_dog
7   TRUE    FALSE       FALSE       no_dog
8   TRUE    TRUE        FALSE       black_dog
9   TRUE    FALSE       TRUE        white_dog

【问题讨论】:

标签: r dplyr tibble


【解决方案1】:

case_when 是您要查找的函数。

library(dplyr)
df <- read.csv(text = "ID,dog,blackfur,whitefur
1,TRUE,FALSE,FALSE
2,TRUE,TRUE,FALSE
3,TRUE,TRUE,FALSE
4,TRUE,FALSE,TRUE
5,TRUE,FALSE,TRUE
6,TRUE,FALSE,TRUE
7,TRUE,FALSE,FALSE
8,TRUE,TRUE,FALSE
9,TRUE,FALSE,TRUE")

df %>%
mutate(name = case_when(dog & blackfur == FALSE & whitefur == FALSE ~ 'no_dog',
                        dog & blackfur & whitefur == FALSE ~ 'black_dog',
                        dog & blackfur == FALSE & whitefur ~ 'white_dog'))

case_when 函数有一个相当不错的小插曲,比我能更好地描述该函数:https://dplyr.tidyverse.org/reference/case_when.html

【讨论】:

    【解决方案2】:

    如果您有data.table,您可以执行以下操作:-

    dt[, sum := 1 * dt$dog + 2 * dt$blackfur + 3 * dt$whitefur]
    dt[, name := ifelse(sum == 1, "no_dog", ifelse(sum == 3, "black_dog", 
                 ifelse(sum == 4, "white_dog", "")))]
    dt[, sum := NULL]
    

    如果您有data.frame,那么您可以执行以下操作:-

    dt$sum <- 1 * dt$dog + 2 * dt$blackfur + 3 * dt$whitefur
    dt$name <-  ifelse(dt$sum == 1, "no_dog", ifelse(dt$sum == 3, "black_dog", ifelse(dt$sum == 4, "white_dog", "")))
    dt["sum"] <- NULL
    

    编辑:数学

    基本上,您将第二列乘以 1,第三列乘以 2,第四列乘以 3,根据哪些列具有 TRUE 和哪些列具有 FALSE 值,您可以获得不同的结果。

    这是因为当不同的列具有 TRUEFALSE 值时,我们不想要相同的值。例如,如果dog == TRUEblackfur == TRUEwhitefur == FALSE,我们的总和将是2。但是如果dog == TRUEwhitefur == TRUEblackfur == FALSE,我们也可以得到2 的总和。因为,我们需要区分这两种情况,我们将第二列加 1,第三列加 2,第四列加 3。

    如果我们这样做,那么dogblackfur 等于TRUE,我们将得到1*1 + 2*1 = 3,并且dogwhitefur 等于TRUE,我们将得到@987654344 @,因此,答案不同。

    这将为我们提供三个唯一值:-

    Condition                  Value
    dog == TRUE -                1
    dog & blackfur == TRUE       3
    dog & whitefur == TRUE       4
    

    根据这些值,我们可以链接ifelse 以获得name 列的不同值。如果sum == 1,那么我们得到no_dog。否则,如果sum == 3,那么我们得到black_dog。否则,如果sum == 4,那么我们得到black_dog

    【讨论】:

    • 可以通过向新来的 OP 解释 1 和 0 与数学背后的 TRUE 和 FALSE 的关系以及 ifelse 的链接来提及。
    【解决方案3】:

    这只满足第一个条件。

    dat1 = data.frame(dog = TRUE, blackfur = FALSE, whitefur = FALSE)
    
     library(tidyverse)
        dat1 = dat1 %>% mutate(name = if(dog == TRUE){
          if(blackfur == FALSE){
            if( whitefur == FALSE){
              name = "nod_dog"
            }
          }
          
        })
    

    【讨论】:

    • 一些建议:你不需要加载所有的 tidyverse 包,因为你只使用 dplyr。对于像这样测试条件操作,测试一组有代表性的条件非常重要,而不仅仅是单行。如果它只在一种情况下有效,那么它并不是那么有用。您还使用 if / else 进行向量化操作。你也拼错了“no_dog”
    【解决方案4】:

    这直接在相关列上使用逻辑运算符。

    
    df <- read.csv(text = "ID,dog,blackfur,whitefur,name
    1,TRUE,FALSE,FALSE,no_dog
    2,TRUE,TRUE,FALSE,black_dog
    3,TRUE,TRUE,FALSE,black_dog
    4,TRUE,FALSE,TRUE,white_dog
    5,TRUE,FALSE,TRUE,white_dog
    6,TRUE,FALSE,TRUE,white_dog
    7,TRUE,FALSE,FALSE,no_dog
    8,TRUE,TRUE,FALSE,black_dog
    9,TRUE,FALSE,TRUE,white_dog")
    
    df$name <- ifelse(
            df$dog & !df$blackfur & !df$whitefur,
            "no_dog",
            ifelse(df$blackfur, "black_dog", "white_dog")
    )
    
    

    【讨论】:

      猜你喜欢
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多