R 如何使用case_when而不是if_else[我的代码中有错误?]

R 如何使用case_when而不是if_else[我的代码中有错误?],r,dplyr,vectorization,tidyverse,case-when,R,Dplyr,Vectorization,Tidyverse,Case When,我试图了解为什么我不能在when而不是dplyr::if_else时使用dplyr::case_。 也许我遗漏了什么。让我解释一下: 我做了这个手术,效果很好: df %>% mutate( keep = if_else( assembly_level != "Complete Genome" | genome_rep != "Full", FALSE, ifelse( version_status == "suppresse

我试图了解为什么我不能在when而不是dplyr::if_else时使用dplyr::case_。 也许我遗漏了什么。让我解释一下:

我做了这个手术,效果很好:

df %>%
  mutate(
    keep = if_else(
      assembly_level != "Complete Genome" | genome_rep != "Full",
      FALSE,
      ifelse(
        version_status == "suppressed",
        FALSE,
        if_else(
          refseq_category %in% c("reference genome", "representative genome"),
          TRUE,
          if_else(
            rpseudo > 0.4,
            FALSE,
            TRUE
          )
        )
      )
    )
  )
但是,当我尝试使用case_时

我得到了不同的结果

我认为问题在于函数的使用

如果您需要这些数据,它是一个通用的公共数据,可以在此处下载:

要获得:

read_tsv("ftp://ftp.ncbi.nlm.nih.gov/genomes/ASSEMBLY_REPORTS/assembly_summary_refseq.txt", 
         comment = "#",
         col_names = c(
           "assembly", "bioproject", "biosample", 
           "wgs_master", "refseq_category", "taxid", 
           "species_taxid", "organism_name", "infraspecific_name", 
           "isolate", "version_status", "assembly_level", 
           "release_type", "genome_rep", "seq_rel_date", 
           "asm_name", "submitter", "gbrs_paired_asm", 
           "paired_asm_comp", "ftp_path", "excluded_from_refseq", "relation_to_type_material"
         )
) %>%
  select(assembly, refseq_category, 
         assembly_level, genome_rep, 
         version_status, release_type) %>%
  mutate(
    rpseudo = runif(nrow(.), 0, 1)
  ) -> df
# it will got some warnings
提前感谢,

数据中有NA。在df1中存储if_else的输出,在df2中存储带有case_的输出。df1$keep和df2$keep之间的唯一区别是,df1$keep中几乎没有NAs,而在这些地方,case_获得了一些实际值。检查

table(df1$keep, useNA = "always")
# FALSE   TRUE   <NA> 
#156616  10386     79 

table(df2$keep, useNA = "always")
# FALSE   TRUE   <NA> 
#156647  10434      0 
此外,如果删除这些NA值,然后检查df1和df2中的值,则它们是相同的

all(df1$keep[!is.na(df1$keep)] == df2$keep[!is.na(df1$keep)])
#[1] TRUE
在if_else和case_when中处理NA的方式不同。考虑这个简化的例子,以便更好地理解。
library(dplyr)
df <- data.frame(a = c(1:3, NA, 4:7), b = c(NA, letters[1:7]))
但是,在case_中,当输出为

df %>%
   mutate(res = case_when(a > 3 ~ "Yes", 
                          b == "c"~"No", 
                          a > 5 ~ "Maybe", 
                          TRUE ~ "Done"))

#   a    b  res
#1  1 <NA> Done
#2  2    a Done
#3  3    b Done
#4 NA    c   No
#5  4    d  Yes
#6  5    e  Yes
#7  6    f  Yes
#8  7    g  Yes
数据中有NA。在df1中存储if_else的输出,在df2中存储带有case_的输出。df1$keep和df2$keep之间的唯一区别是,df1$keep中几乎没有NAs,而在这些地方,case_获得了一些实际值。检查

table(df1$keep, useNA = "always")
# FALSE   TRUE   <NA> 
#156616  10386     79 

table(df2$keep, useNA = "always")
# FALSE   TRUE   <NA> 
#156647  10434      0 
此外,如果删除这些NA值,然后检查df1和df2中的值,则它们是相同的

all(df1$keep[!is.na(df1$keep)] == df2$keep[!is.na(df1$keep)])
#[1] TRUE
在if_else和case_when中处理NA的方式不同。考虑这个简化的例子,以便更好地理解。
library(dplyr)
df <- data.frame(a = c(1:3, NA, 4:7), b = c(NA, letters[1:7]))
但是,在case_中,当输出为

df %>%
   mutate(res = case_when(a > 3 ~ "Yes", 
                          b == "c"~"No", 
                          a > 5 ~ "Maybe", 
                          TRUE ~ "Done"))

#   a    b  res
#1  1 <NA> Done
#2  2    a Done
#3  3    b Done
#4 NA    c   No
#5  4    d  Yes
#6  5    e  Yes
#7  6    f  Yes
#8  7    g  Yes

请不要因为易于编写而将TRUE/FALSE缩写为T/FIs,我在代码中更改了它。我理解这一点,但我不建议使用它,因为您可以将T/F指定为对象标识符,如果不正确检查,这可能会产生巨大问题。您的代码在.F.x[[I]]中不可复制错误,…:找不到对象“程序集”。是否有忘记复制的步骤?在读取数据时,选择中的列名与col_names=中的列名不匹配。这应该会给您带来一个错误。请不要仅仅因为易于编写而将TRUE/FALSE缩写为T/FIs,我在代码中对其进行了更改。我理解这一点,但我不建议使用它,因为您可以将T/F指定为对象标识符,如果不正确检查,这可能会造成巨大问题。您的代码在.F.x[[I]]中不可复制错误, ... : 找不到对象“程序集”。是否有忘记复制的步骤?在读取数据时,选择中的列名与col_names=中的列名不匹配。这应该给你一个错误。