【问题标题】:Data Split based on a logical relationship in R基于 R 中的逻辑关系的数据拆分
【发布时间】:2016-07-17 22:15:45
【问题描述】:

我有一个包含历史数据的数据集,我想将其分成两组:

  1. 我拥有至少连续两年数据的一组 ID。
  2. 它是补码,即我从它们那里获得一年或多年数据但不连续年份的一组 ID。

以数据集A为例:

A =
ID    Year    X   Y
1     2010    2   3
1     2012    4   0
2     2011    4   3
2     2012    2   2
3     2010    3   1
3     2012    2   1
3     2013    0   3

我想拿到B组:

B = 
ID    Year    X   Y
2     2011    4   3
2     2012    2   2
3     2012    2   1
3     2013    0   3

B'=
ID    Year    X   Y
1     2010    2   3
1     2012    4   0
3     2010    3   1

请注意,ID 3 在BB' 中都显示,因为它有连续年份和单个年份的记录。

我不必在 R 中执行此操作,我也可以使用 Python。任何帮助将不胜感激。

【问题讨论】:

    标签: python r logical-operators data-cleaning


    【解决方案1】:

    dplyr

    library(dplyr)
    df %>% group_by(ID) %>% filter(Year %in% c(Year - 1, Year + 1))
    # Source: local data frame [4 x 4]
    # Groups: ID [2]
    # 
    #      ID  Year     X     Y
    #   (int) (int) (int) (int)
    # 1     2  2011     4     3
    # 2     2  2012     2     2
    # 3     3  2012     2     1
    # 4     3  2013     0     3
    

    df %>% group_by(ID) %>% filter(!Year %in% c(Year - 1, Year + 1))
    # Source: local data frame [3 x 4]
    # Groups: ID [2]
    # 
    #      ID  Year     X     Y
    #   (int) (int) (int) (int)
    # 1     1  2010     2     3
    # 2     1  2012     4     0
    # 3     3  2010     3     1
    

    这个想法非常简单:group_by(ID) 分别评估每个 ID,然后 filter 仅评估具有 Year 值的行,该值比所有 Year 值小一或大一群组。添加! 以反转逻辑并获取不满足该条件的行。

    【讨论】:

    • 您可以使用 df[order(df$ID),][unlist(tapply(df$Year, df$ID, function(x){x %in% c(x + 1, x - 1)})),] 之类的东西将逻辑转换为基础,但这并不那么漂亮。
    【解决方案2】:

    您可以尝试使用 base R diff

    查找Year 列中相差 1 年的行的索引,获取下一行的索引并对它们进行子集化。

    df[sort(c(which(diff(df$Year) == 1), 
                    which(diff(df$Year) == 1) + 1)), ]
    
    #  ID Year X Y
    #3  2 2011 4 3
    #4  2 2012 2 2
    #6  3 2012 2 1
    #7  3 2013 0 3
    

    获取不属于第一个子集的所有行

    df[!1:nrow(df) %in% c(which(diff(df$Year) == 1), 
                              which(diff(df$Year) == 1) + 1), ]
    
    #   ID Year X Y
    #1   1 2010 2 3
    #2   1 2012 4 0
    #5   3 2010 3 1
    

    【讨论】:

      【解决方案3】:

      data.table

      library(data.table)
      setDT(A)[,  .SD[Year %in% c(Year-1, Year+1)] , ID]
      #   ID Year X Y
      #1:  2 2011 4 3
      #2:  2 2012 2 2
      #3:  3 2012 2 1
      #4:  3 2013 0 3
      

      或者

      setDT(A)[,  .SD[!Year %in% c(Year-1, Year+1)] , ID]
      #   ID Year X Y
      #1:  1 2010 2 3
      #2:  1 2012 4 0
      #3:  3 2010 3 1
      

      对于这两种情况。

      另一种选择是

      setDT(A)[A[,  {i1 <- .I[(Year - shift(Year, fill= Year[1]))==1]
                     c(i1-1,i1) }, ID]$V1]
      

      【讨论】:

        猜你喜欢
        • 2021-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-18
        • 1970-01-01
        • 2021-09-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多