【问题标题】:Mutate with nested ifesle使用嵌套的 if else 进行变异
【发布时间】:2020-08-25 01:48:17
【问题描述】:

我确实得到了错误的结果,我做错了什么?

df <- data.frame(x=c(1,1,NA),y=c(1,NA,NA),z=c(NA,NA,NA))
df <-mutate(df,result=ifelse(is.na(x),NA,ifelse(any(!is.na(y),!is.na(z)),1,0)))

我明白了(数据[2,4]==0)

   x  y  z result
1  1  1 NA      1
2  1 NA NA      1
3 NA NA NA     NA

而不是这个:

df_wanted <- data.frame(x=c(1,1,NA),y=c(1,NA,NA),z=c(NA,NA,NA), result=c(1,0,NA))

   x  y  z result
1  1  1 NA      1
2  1 NA NA      0
3 NA NA NA     NA

【问题讨论】:

    标签: r dataframe if-statement dplyr


    【解决方案1】:

    我们可以使用| 代替any,因为any 返回单个TRUE/FALSE 作为输出

    with(df, any(!is.na(y), !is.na(z)))
    #[1] TRUE
    

    这会被整个列回收,因为第一个带有“x”的ifelse已经返回第三行的“NA”,所有其他的都返回1

    相反,我们需要为每一行执行此操作,这可以通过 | 完成

    library(dplyr)
    df %>%
       mutate(result = ifelse(is.na(x), NA, ifelse(!is.na(y)|!is.na(z), 1, 0)))
    #   x  y  z result
    #1  1  1 NA      1
    #2  1 NA NA      0
    #3 NA NA NA     NA
    

    或者另一个选项是case_when

    df %>%
      mutate(result = case_when(is.na(x) ~ NA_integer_, 
                            !is.na(y)| !is.na(z) ~ 1L, 
                            TRUE ~ 0L))
    #   x  y  z result
    #1  1  1 NA      1
    #2  1 NA NA      0
    #3 NA NA NA     NA
    

    或者coalesce

    df %>%
       mutate(result = x * +coalesce(!is.na(y)|!is.na(z)))
    #   x  y  z result
    #1  1  1 NA      1
    #2  1 NA NA      0
    #3 NA NA NA     NA
    

    【讨论】:

    • 回答如此之快,我不得不等待绿色勾选它!
    【解决方案2】:

    您可以使用case_when 并明确提及每个条件。

    library(dplyr)
    
    df %>%
      mutate(result = case_when(is.na(x) ~ NA_integer_, 
                                !(is.na(y) & is.na(z)) ~ 1L, 
                                TRUE ~ 0L))
    
    
    #   x  y  z result
    #1  1  1 NA      1
    #2  1 NA NA      0
    #3 NA NA NA     NA
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多