根据每年变化的最大值和最小值过滤数据库

问题描述 投票:0回答:2

我有一个如下所示的数据库:

    Year ID Date Occupy
    2010 1  10   Yes
    2010 2  11   No
    2010 3  12   Yes
    2010 4  9    No
    2010 5  15   No
    2011 7  7    Yes
    2011 8  9    Yes
    2011 9  10   Yes
    2011 11 12   No

我正在尝试创建一个代码,首先检查每年哪些日期是第一个和最后一个被占用的日期(这里的日期是该月的日期)。在 2010 年,这些日期应该是 10 和 12,在 2011 年,这些日期应该是 7 和 10。然后代码应该过滤掉那些日期小于或大于这些第一个和最后一个占用日期的行。

结果应该是:

    Year ID Date Occupy
    2010 1  10   Yes
    2010 2  11   No
    2010 3  12   Yes
    2011 7  7    Yes
    2011 8  9    Yes
    2011 9  10   Yes
  

我尝试使用以下方法在两个单独的部分中执行这两个步骤:

    lapply(function(x) c(min(x), max(x)))

然后使用 lubridate 进行分组和过滤,但一切都会崩溃或不是我想要的。

r filter group-by max min
2个回答
0
投票

单行

data.table
方法(可能不是最优雅的方法,但我最终想不出另一种方法;-))

library(data.table)
mydata <- fread("    Year ID Date Occupy
                 2010 1  10   Yes
                 2010 2  11   No
                 2010 3  12   Yes
                 2010 4  9    No
                 2010 5  15   No
                 2011 7  7    Yes
                 2011 8  9    Yes
                 2011 9  10   Yes
                 2011 11 12   No")

# or setDT(mydata)
mydata[mydata[Occupy == "Yes", .(min = min(Date), max = max(Date)), Year], 
   .(Year = x.Year, ID = x.ID, Date = x.Date, Occupy = x.Occupy), 
   on = .(Year, Date >= min, Date <= max)]

#    Year ID Date Occupy
# 1: 2010  1   10    Yes
# 2: 2010  2   11     No
# 3: 2010  3   12    Yes
# 4: 2011  7    7    Yes
# 5: 2011  8    9    Yes
# 6: 2011  9   10    Yes

其他方法,相同的结果,更短的代码

mydata[ID %in% mydata[mydata[Occupy == "Yes", .(min = min(Date), max = max(Date)), Year], 
                      ID, on = .(Year, Date >= min, Date <= max)], ]

0
投票

如果您更喜欢

dplyr
语法:

library(dplyr)

df <- tribble(
        ~Year, ~ID, ~Date, ~Occupy,
         2010,   1,    10,   "Yes",
         2010,   2,    11,    "No",
         2010,   3,    12,   "Yes",
         2010,   4,     9,    "No",
         2010,   5,    15,    "No",
         2011,   7,     7,   "Yes",
         2011,   8,     9,   "Yes",
         2011,   9,    10,   "Yes",
         2011,  11,    12,    "No"
        )

df |> 
  mutate(
    min_occupied = min(Date[Occupy == "Yes"]),
    max_occupied = max(Date[Occupy == "Yes"]),
    .by = Year
  ) |> 
  filter(between(Date, min_occupied, max_occupied))
#> # A tibble: 6 × 6
#>    Year    ID  Date Occupy min_occupied max_occupied
#>   <dbl> <dbl> <dbl> <chr>         <dbl>        <dbl>
#> 1  2010     1    10 Yes              10           12
#> 2  2010     2    11 No               10           12
#> 3  2010     3    12 Yes              10           12
#> 4  2011     7     7 Yes               7           10
#> 5  2011     8     9 Yes               7           10
#> 6  2011     9    10 Yes               7           10

创建于 2023-11-08,使用 reprex v2.0.2

© www.soinside.com 2019 - 2024. All rights reserved.