r-删除一列中具有重复值的行,但仅当最近一行的另一列具有特定值时

  • 本文关键字:一列 最近 一行 删除 r duplicates
  • 更新时间 :
  • 英文 :


考虑以下数据帧

address <- c('9A Eagle Point N','9A Eagle Point N','9A Eagle Point N', '9999 Mineral Wells Highway', '9999 Mineral Wells Highway')
sale_status <- c('Succeeded', 'Failed', 'Failed', 'Failed', 'Failed')
sale_date <- as.Date(c('2020-03-01','2020-02-01', '2020-01-14', '2020-03-02', '2019-08-01'))
df = data.frame(address, sale_status, sale_date)

这样数据看起来像这样:

1           9A Eagle Point N   Succeeded 2020-03-01
2           9A Eagle Point N      Failed 2020-02-01
3           9A Eagle Point N      Failed 2020-01-14
4 9999 Mineral Wells Highway      Failed 2020-03-02
5 9999 Mineral Wells Highway      Failed 2019-08-01

我正在尝试编写代码,以便对于具有匹配地址的任意数量的n行,只要在第二次到最近一次销售日期的180天内成功销售了最后一行,就会删除较早的匹配(重复(行。我只想在最新的行的sale_status为"成功(df$sale_status == "Succeeded(",而较早的匹配行的sale_status为"失败"(df$sale_status == "Failed"(时删除以前的匹配行

我知道这听起来令人难以置信的复杂,但任何帮助都将不胜感激。我查看了其他几个发布的问题,但似乎没有一个能解决这个用例。

我相信得到的数据帧会是这样的:

1           9A Eagle Point N   Succeeded 2020-03-01
4 9999 Mineral Wells Highway      Failed 2020-03-02
5 9999 Mineral Wells Highway      Failed 2019-08-01

以下是从dplyr使用lag的方法。

首先,我们用lag计算每个地址的日期之间的天数差。然后,我们用cumsum计算从最终成功日期到过去的累计天数。然后我们过滤满足以下任意条件的行:

  1. 成功
  2. 从未售出
  3. 在销售成功前180多天失败
library(dplyr)
df %>%
arrange(desc(sale_date)) %>%
group_by(address) %>% 
mutate(elapsed = sale_date - lag(sale_date,1L,default=first(sale_date)),
cumelapse = cumsum(as.integer(elapsed)),
sold = any(sale_status == "Succeeded")) %>%
filter( sale_status == "Succeeded" | sold == FALSE | (sold == TRUE & cumelapse < -180)) %>%
ungroup %>% arrange(address,sale_date)
#  address                    sale_status sale_date  elapsed   cumelapse sold 
#  <fct>                      <fct>       <date>     <drtn>        <int> <lgl>
#1 9999 Mineral Wells Highway Failed      2019-08-01 -214 days      -214 FALSE
#2 9999 Mineral Wells Highway Failed      2020-03-02    0 days         0 FALSE
#3 9A Eagle Point N           Succeeded   2020-03-01    0 days         0 TRUE 

我们可以检查每个address中的anysale_status == 'Succeeded',并只选择大于相应sale_date的行。

library(dplyr)
df %>%
group_by(address) %>%
filter(if(any(sale_status == 'Succeeded')) 
sale_date >= sale_date[which.max(sale_status == 'Succeeded')] else TRUE)
#  address                    sale_status sale_date 
#  <fct>                      <fct>       <date>    
#1 9A Eagle Point N           Succeeded   2020-03-01
#2 9999 Mineral Wells Highway Failed      2020-03-02
#3 9999 Mineral Wells Highway Failed      2019-08-01

最新更新