【问题标题】:Select all unique entries showing a minimum of n records in a time range选择在一个时间范围内至少显示 n 条记录的所有唯一条目
【发布时间】:2020-04-17 12:24:41
【问题描述】:

我有以下按监测点和采样年份组织的水化合物年均值数据集(32000个条目),示例如下:

data= data.frame(Site_ID=c(1, 1, 1, 2, 2, 2, 3, 3, 3), Year=c(1976, 1977, 1978, 2004, 2005, 2006, 2003, 2004, 2005), AnnualMean=c(1.1, 1.2, 1.1, 2.1, 2.6, 3.1, 2.7, 2.6, 1.9))

我只想从所有监测站点中选择在 year1 和 year2 之间至少有 n 个测量值的数据?通常,我想从显示 1990 年到 2005 年之间的 10 个测量值的监测站点中选择所有数据。到目前为止,我尝试过但没有成功:

data %>%
group_by(Site_ID) %>%
filter(n()>=n %in% between(Year, year1, year2))

【问题讨论】:

    标签: r filter range subset


    【解决方案1】:

    这会选择在parms['yr1']parms['yr2'] 之间至少包含parms['n'] 观察的所有Site_ID 组。

    library(data.table)
    setDT(df)
    
    parms <- c(n = 2, yr1 = 2000, yr2 = 2005)
    
    df[, if(sum(Year %between% parms[c('yr1', 'yr2')]) >= parms['n']) .SD, 
       by = Site_ID]
    
    #    Site_ID Year AnnualMean
    # 1:       2 2004        2.1
    # 2:       2 2005        2.6
    # 3:       2 2006        3.1
    # 4:       3 2003        2.7
    # 5:       3 2004        2.6
    # 6:       3 2005        1.9
    

    【讨论】:

    • 这个解决方案效果很好,非常感谢您,并为延迟回复道歉!
    【解决方案2】:

    我不确定这是否是您的预期结果,也许您可​​以尝试一下

    data %>%
      group_by(Site_ID) %>%
      filter(between(Year,1990,2005)) %>%
      filter(Year, n()>=10)
    

    一个基本的 R 替代方案是

    subset(data,
           !!ave(ave(Year,
                     Site_ID,
                     FUN = function(x) x>=1990&x<=2005),
                 Site_ID,
                 FUN = function(x) sum(x)>2))
    

    【讨论】:

      【解决方案3】:

      Base-R 中的此代码适用于您提供的示例数据。您可以更改 IDstoGet &lt;- Site_IDs[CountBySite_IDs &gt;= 3] 中的数字,以仅采用具有超过您想要的任何数量的数据点的 Site_ID。

      DataInRange <- data[(data$Year>=1990&data$Year<=2005),]
      Site_IDs <- unique(DataInRange$Site_ID)
      CountBySite_IDs <- sapply(Site_IDs, function(x) length(grep(x,DataInRange$Site_ID)))
      IDstoGet <- Site_IDs[CountBySite_IDs >= 3]
      DataToGetPosition <- unlist(lapply(IDstoGet, grep, DataInRange$Site_ID))
      
      DataInRange[DataToGetPosition,]
      

      输出

      > DataInRange[DataToGetPosition,]
        Site_ID Year AnnualMean
      7       3 2003        2.7
      8       3 2004        2.6
      9       3 2005        1.9
      

      【讨论】:

        【解决方案4】:

        基础 R 解决方案:

        # Store a scalar that's values represent the number of observations 
        # You would like to filter the data set for: n => numeric vector: 
        n <- 10
        
        # Append a site count vector to a subset of the original df: sites_counted_df => data.frame:
        sites_counted_df <-
          within(data[which(data$Year >= 1980 & data$Year <= 2005), ],
                 {
                   count <- ave(Site_ID, Site_ID, FUN = length)
                 }
          )
        
        # Filter the data.frame to contain records for sites above "n":
        # n_observation_sites => data.frame
        n_observation_sites <- sites_counted_df[which(count > n),]
        

        数据:

        data <- data.frame(
          Site_ID = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
          Year = c(1976, 1977, 1978, 2004, 2005, 2006, 2003, 2004, 2005),
          AnnualMean = c(1.1, 1.2, 1.1, 2.1, 2.6, 3.1, 2.7, 2.6, 1.9)
        )
        

        【讨论】:

          猜你喜欢
          • 2020-07-29
          • 1970-01-01
          • 2012-09-19
          • 2017-03-06
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-02
          相关资源
          最近更新 更多