识别重复值,包括R中的第一个值

时间:2014-09-24 18:11:46

标签: r

我的数据如下:

ROW  ID   DATE  
1    1    09/20/2014
2    1    09/21/2014
3    1    09/22/2014
4    1    09/22/2014
5    2    09/19/2014
6    2    09/20/2014
7    2    09/21/2014
8    2    09/21/2014
9    2    09/21/2014
10   3    09/18/2014
11   3    09/19/2014
12   3    09/20/2014
13   3    09/20/2014

我想创建一个列FL以按ID识别重复日期,我知道duplicated()将识别后续重复值,但我也想在开始重复之前识别第一个值

我的数据应如下所示:

ROW  ID   DATE         FL
1    1    09/20/2014    0
2    1    09/21/2014    0
3    1    09/22/2014    1
4    1    09/22/2014    1
5    2    09/19/2014    0
6    2    09/20/2014    0
7    2    09/21/2014    1
8    2    09/21/2014    1
9    2    09/21/2014    1
10   3    09/18/2014    0 
11   3    09/19/2014    0
12   3    09/20/2014    1
13   3    09/20/2014    1

因此,对于每个ID,非重复日期的FL值为0,重复日期的FL值为1.如果您可以帮我使用R代码来执行此操作,那将会很棒。谢谢。

修改

这里是数据的输入:

structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L), 
              DATE = structure(c(3L, 4L, 5L, 5L, 2L, 3L, 4L, 4L, 4L, 1L, 2L, 3L, 3L), 
              .Label = c("9/18/2014", "9/19/2014", "9/20/2014", "9/21/2014", "9/22/2014"), 
                        class = "factor")), 
              .Names = c("ID", "DATE"), class = "data.frame", row.names = c(NA, -13L)) 

3 个答案:

答案 0 :(得分:2)

使用data.table包:

使用类似的内容
 library(data.table)
 setDT(dat)[,FL := (duplicated(DATE) | duplicated(DATE, fromLast = TRUE))*1,ID]
    ID      DATE FL
 1:  1 9/20/2014  0
 2:  1 9/21/2014  0
 3:  1 9/22/2014  1
 4:  1 9/22/2014  1
 5:  2 9/19/2014  0
 6:  2 9/20/2014  0
 7:  2 9/21/2014  1
 8:  2 9/21/2014  1
 9:  2 9/21/2014  1
10:  3 9/18/2014  0
11:  3 9/19/2014  0
12:  3 9/20/2014  1
13:  3 9/20/2014  1

或者在基础R中(使用@akrun道具):

transform(dat, ave(as.numeric(factor(DATE)), ID, 
           FUN=function(x) duplicated(x)|duplicated(x,fromLast=TRUE)))

答案 1 :(得分:1)

Fwiw,这是解决这个问题的一种粗暴方式。

# your original data frame
dat <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L), 
         DATE = structure(c(3L, 4L, 5L, 5L, 2L, 3L, 4L, 4L, 4L, 1L, 2L, 3L, 3L), 
           .Label = c("9/18/2014", "9/19/2014", "9/20/2014", "9/21/2014", "9/22/2014"), 
           class = "factor")), 
         .Names = c("ID", "DATE"), class = "data.frame", row.names = c(NA, -13L))

# glue the columns to avoid need of grouping by ID first
dat2 <- paste(dat$ID, dat$DATE, sep='/')
# alternatively, you can use following for string comparison, if needed.
# dat2<-paste(as.character(dat$ID),as.character(dat$DATE),sep='/')

# create a lookup table for counts of each ID+DATE combo
lookup<-table(dat2)

# add a column based on counts. If count is 1 then ID+DATE is not duplicated.
dat$FL <- sapply(dat2,FUN = function(x) { if (lookup[x] == 1) 0 else 1})

# output
print(dat)

这应该可以为您提供所需的信息。

   ID      DATE FL
1   1 9/20/2014  0
2   1 9/21/2014  0
3   1 9/22/2014  1
4   1 9/22/2014  1
5   2 9/19/2014  0
6   2 9/20/2014  0
7   2 9/21/2014  1
8   2 9/21/2014  1
9   2 9/21/2014  1
10  3 9/18/2014  0
11  3 9/19/2014  0
12  3 9/20/2014  1
13  3 9/20/2014  1

有更复杂的方法可以做到这一点,table()有其局限性,但在大多数情况下,这很简单,易于阅读,并且应该为您完成工作。

答案 2 :(得分:0)

dplyr + magrittr替代方:

dat %>% 
    group_by(ID, DATE) %>% 
    mutate(FL = ifelse(n() > 1, 1, 0))

有点缺点:每个重复日期都会产生1,而不是最新的。看看是否不方便。