【问题标题】:How to properly filter a df based on a condition in R?如何根据 R 中的条件正确过滤 df?
【发布时间】:2021-02-12 11:38:21
【问题描述】:

我正在尝试根据日期类列对数据集进行采样, “活跃”每季度一次,“非活跃”每月一次

这是我的代码:

library(dplyr)
library(lubridate)
  
## data ##
                 
df <- structure(list( 
             mes = c("01/01/2000", "01/02/2000", "01/03/2000", 
"01/04/2000", "01/05/2000", "01/06/2000", "01/07/2000", "01/08/2000", 
"01/09/2000", "01/10/2000", "01/11/2000", "01/12/2000"),
              status = c("Active", "Inactive",
                         "Active", "Inactive",
                         "Active", "Inactive",
                         "Active", "Active",
                         "Inactive", "Active",
                         "Inactive", "Active")),
             class = "data.frame",
             row.names = c(NA, -12L))

## setting date class for "mes" column ##

df$mes <- as.Date(df$mes,
                  format = "%d/%m/%Y")

## sampling ##

sample_df <- df %>%  
  dplyr :: filter(status %in% "Active",
                  status %in% "Inactive") %>%
            dplyr :: filter_if(status == "Active",
            month(mes) %in% c(3,6,9,12),
            month(mes) %in% c(1,2,3,4,5,6,7,8,9,10,11,12))

控制台输出:

Error in is_logical(.p) : objeto 'status' no encontrado

我可以使用任何其他库来完成这项任务吗?

【问题讨论】:

  • 查看@akrun 提供的解决方案。出于我自己的好奇心,您能否更新您的问题并提供预期的输出?
  • 该错误是由于filter_if 的语法不正确造成的。也不是现在推荐使用across 代替filter_if,并且它们都用于选择列名而不是变量值的上下文中。
  • 完全不清楚你想要什么作为输出。

标签: r dataframe if-statement filter dplyr


【解决方案1】:

对于dplyr::filter,如果我们使用,,那么它意味着&amp;,相反,我们需要|。使用&amp; 将导致0 rows,因为“状态”不能在同一位置同时具有“活动”和“非活动”

df %>%  
  dplyr::filter(status %in% "Active"| status %in% "Inactive") %>% 
  dplyr::filter(status == 'Active', month(mes) %in% c(3, 6, 9, 12))

此外,由于我们使用%in%,它可以在%in% 运算符的rhs 中使用vector 值和length >= 1

 df %>%
    dplyr::filter(status %in% c("Active", "Inactive")) %>%      
    dplyr::filter(status == 'Active', month(mes) %in% c(3, 6, 9, 12))

在 OP 的过滤器语句中

...
 month(mes) %in% c(3,6,9,12),
        month(mes) %in% c(1,2,3,4,5,6,7,8,9,10,11,12)

暗示两个条件都应该为真,但其中一个是另一个条件的子集

【讨论】:

    【解决方案2】:

    要过滤"Active" 状态的季度月份和“非活动”的所有月份,您可以这样做:

    library(dplyr)
    
    df %>%
      mutate(month = lubridate::month(mes)) %>%
      filter(status == "Active" & month %in% c(3,6,9,12) | 
             status == "Inactive" & month %in% 1:12)
    
    #         mes   status month
    #1 2000-02-01 Inactive     2
    #2 2000-03-01   Active     3
    #3 2000-04-01 Inactive     4
    #4 2000-06-01 Inactive     6
    #5 2000-09-01 Inactive     9
    #6 2000-11-01 Inactive    11
    #7 2000-12-01   Active    12
    

    由于您希望所有月份都处于“非活动”状态,您也可以这样做:

    df %>%
      mutate(month = lubridate::month(mes)) %>%
      filter(status == "Active" & month %in% c(3,6,9,12) | 
             status == "Inactive")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 2022-09-29
      • 2022-08-03
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2021-06-25
      • 2022-09-22
      相关资源
      最近更新 更多