【问题标题】:Finding the common dates in a data set based on a categorical variable根据分类变量查找数据集中的常见日期
【发布时间】:2017-05-11 13:03:29
【问题描述】:

我有一个看起来像这样的数据集:

id    eye    date       notes
1      L   01-01-2000
1      L   01-06-2000
1      R   01-01-2000
1      R   01-03-2000
1      R   01-06-2000
2      L   01-01-2000
2      L   01-04-2000
2      R   01-04-2000
2      R   01-07-2000
2      R   04-09-2001
3      L   01-01-2000
4      L   01-01-2000
4      L   03-03-2001
4      R   03-03-2001

对于每个id,我希望能够找到眼睛标记为 L 和 R 的常见日期,然后将其作为数据框输出。所以它应该是这样的:

id    eye    date       notes
1      L   01-01-2000
1      L   01-06-2000
1      R   01-01-2000
1      R   01-06-2000
2      L   01-04-2000
2      R   01-04-2000
4      L   03-03-2001
4      R   03-03-2001

我一直在尝试 dplyrplyr 的不同变体(下面的示例),但我似乎无法让它做我想做的事。

data %>% group_by(id) %>% do(Reduce(intersect, list(.$date[.$eye == "L"], .$date[.$eye == "R"])))

ddply(data, .(id), summarize, Reduce(intersect, list(.$date[.$eye == "L"], .$date[.$eye == "R"])))

从语义上讲,这两个似乎都“说出”了我想让他们做什么,但我没有得到任何清晰的结果。

有什么想法吗?

【问题讨论】:

  • 我已经更新了示例。 L 和 R 的条目不必成对出现。一个可能有很多,另一个可能很少(或没有)。我正在为每个 ID 查找特定日期的所有 L/R 对。我希望这很清楚!

标签: r dplyr plyr


【解决方案1】:

我们也可以使用data.table

library(data.table)
setDT(df1)[,  .SD[(uniqueN(eye)>1) & !duplicated(eye)], date]
#         date id eye
#1: 01-01-2000  1   L
#2: 01-01-2000  1   R
#3: 01-06-2000  1   L
#4: 01-06-2000  1   R
#5: 01-04-2000  2   L
#6: 01-04-2000  2   R

【讨论】:

    【解决方案2】:

    如果在一个 id-date 有两个观察值时总是有一个 L 和一个 R,就像您的示例数据一样,那么您可以像这样使用 duplicated

    dat[duplicated(dat[-2]) | duplicated(dat[-2], fromLast = TRUE),]
       id eye       date
    1   1   L 01-01-2000
    2   1   L 01-06-2000
    3   1   R 01-01-2000
    5   1   R 01-06-2000
    7   2   L 01-04-2000
    8   2   R 01-04-2000
    13  4   L 03-03-2001
    14  4   R 03-03-2001
    

    如果您需要检查 L 和 R 是否都存在于 id-date 对中,您可以保存上述结果并使用 ave 执行这样的检查

    temp <- dat[duplicated(dat[-2]) | duplicated(dat[-2], fromLast = TRUE),]
    temp[as.logical(ave(as.character(temp$eye), temp$id, temp$date,
                        FUN=function(x) all(x %in% c("L", "R")))),]
       id eye       date
    1   1   L 01-01-2000
    2   1   L 01-06-2000
    3   1   R 01-01-2000
    5   1   R 01-06-2000
    7   2   L 01-04-2000
    8   2   R 01-04-2000
    13  4   L 03-03-2001
    14  4   R 03-03-2001
    

    【讨论】:

    • 感谢您的回复。它们并不总是成对出现,R 可以有任意数量的不同日期,L 可以有任意(可能不同)数量的日期。我将编辑我的帖子。
    【解决方案3】:

    使用 dplyr 你可以使用filter:

    dat %>%
      group_by(date) %>%
      filter(sum(eye == "L") > 0 & sum(eye == "R") > 0 & !(duplicated(date) & duplicated(eye)))
    
    Source: local data frame [6 x 3]
    Groups: date [3]
    
         id    eye       date
      <int> <fctr>     <fctr>
    1     1      L 01-01-2000
    2     1      L 01-06-2000
    3     1      R 01-01-2000
    4     1      R 01-06-2000
    5     2      L 01-04-2000
    6     2      R 01-04-2000
    

    【讨论】:

      【解决方案4】:

      另一个:

      df <- read.table(header=TRUE, text="id    eye    date
      1      L   01-01-2000
                   1      L   01-06-2000
                   1      R   01-01-2000
                   1      R   01-03-2000
                   1      R   01-06-2000
                   2      L   01-01-2000
                   2      L   01-04-2000
                   2      R   01-04-2000
                   2      R   01-07-2000
                   2      R   04-09-2001
                   3      L   01-01-2000
                   4      L   01-01-2000
                   4      L   03-03-2001
                   4      R   03-03-2001")
      
      library(dplyr)
      
      left_join(df %>%
                   group_by(id,date) %>%
                   summarize(n=n()) %>%
                   filter(n==2) %>%
                   select(-n),
                 df,
                 by=c("id","date")) %>%
        arrange(id,eye,date)
      

      【讨论】:

        猜你喜欢
        • 2022-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-15
        • 2016-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多