删除 r 中有冗余信息的行(不仅仅是重复的)

Delete rows with redundant information in r (not just duplicates)

在此示例数据中:

id<-c(2,2,2,2,2,3,3,3,3,3,3,4,4,4,4)
time<-c(3,5,7,8,9,2,8,10,12,14,18,4,6,7,9)
status<-c('mar','mar','div','c','mar','mar','div','mar','mar','c','div','mar','mar','c','mar')

myd<-data.frame(id,time,status)

   id time status
1   2    3    mar
2   2    5    mar
3   2    7    div
4   2    8      c
5   2    9    mar
6   3    2    mar
7   3    8    div
8   3   10    mar
9   3   12    mar
10  3   14      c
11  3   18    div
12  4    4    mar
13  4    6    mar
14  4    7      c
15  4    9    mar

我需要知道这个人什么时候结婚的(如果有两个连续的 'mar' 行之间没有 'div' 任何地方,这个人从未 div 强迫,因此这是同一次婚姻,并且我们不需要重复信息的时间;mar,c,mar 的序列也是如此,因为未检测到 div,因此 child 之前和之后的婚姻是相同的婚姻,因此是第二次一个可以删除)。我怀疑我需要得到 min(time[status=='mar']) 但如果那个人得到 mar,mar,div,mar,div,mar 序列,这将是不正确的(只有2nd mar需要删除,不是第一个之后的所有)。

所以新数据应该类似于

   id time status
2   2    5    mar
3   2    7    div
4   2    8      c
5   2    9    mar
6   3    2    mar
7   3    8    div
8   3   10    mar
10  3   14      c
11  3   18    div
13  4    6    mar
14  4    7      c

这是我的方法,只适用于一行

myd2<-myd %>% 
  group_by(id) %>% 
  mutate(dum1=ifelse(status=='mar',min(time[status=='mar']),NA),
         dum2=cumsum(status=='div'),
         flag=ifelse(time>dum1 & dum2==0,1,0))

如果我去掉 dum2==0 那么它删除了太多行。

我将通过在分组数据中创建 lag_status 变量来删除状态未更改的行:

> myd %>% 
+     arrange(id, time) %>% 
+     group_by(id) %>% 
+     mutate(lag_status = lag(status)) %>%
+     ungroup() %>% 
+     filter(is.na(lag_status) | status != lag_status) %>% 
+     select(-lag_status)
# A tibble: 12 x 3
      id  time status
   <dbl> <dbl> <fct> 
 1     2     3 mar   
 2     2     7 div   
 3     2     8 c     
 4     2     9 mar   
 5     3     2 mar   
 6     3     8 div   
 7     3    10 mar   
 8     3    14 c     
 9     3    18 div   
10     4     4 mar   
11     4     7 c     
12     4     9 mar

我的做法:

library(dplyr)

myd %>%
  group_by(id) %>% 
  arrange(time) %>%
  filter(status != lag(status) | is.na(lag(status))) %>%
  ungroup() %>%
  arrange(id)

Returns:

# A tibble: 12 x 3
      id  time status
   <dbl> <dbl> <chr>
 1     2     3 mar
 2     2     7 div
 3     2     8 c
 4     2     9 mar
 5     3     2 mar
 6     3     8 div
 7     3    10 mar
 8     3    14 c
 9     3    18 div
10     4     4 mar
11     4     7 c
12     4     9 mar

我在你的 post 中读到两个不同的问题。

  1. 这个人第一次结婚的时间
  2. 如何制作删除冗余状态信息的列表

您似乎对#1 有解决方案,但实际上您想要#2。

我读 #2 是想过滤掉 id 和状态与前一行相同的行。看起来像:

myd %>%
  filter(!(id == lag(id) & status == lag(status))

使用快捷助手功能,

func <- function(x, vals = c("mar", "div")) {
  out <- rep(TRUE, length(x))
  last <- x[1]
  for (ind in seq_along(x)[-1]) {
    out[ind] <- x[ind] != last || !x[ind] %in% vals
    if (out[ind] && x[ind] %in% vals) last <- x[ind]
  }
  out
}

我们可以做到

library(data.table)
as.data.table(myd)[, .SD[func(status),], by = .(id)]
#        id  time status
#     <num> <num> <char>
#  1:     2     3    mar
#  2:     2     7    div
#  3:     2     8      c
#  4:     2     9    mar
#  5:     3     2    mar
#  6:     3     8    div
#  7:     3    10    mar
#  8:     3    14      c
#  9:     3    18    div
# 10:     4     4    mar
# 11:     4     7      c

如果你想在 dplyr 中使用它,那么

library(dplyr)
myd %>%
  group_by(id) %>%
  filter(func(status))