【问题标题】:Subset rows based on increments which got changed - R基于已更改的增量的子集行 - R
【发布时间】:2021-09-04 21:39:18
【问题描述】:

我想对数据框/表中的某些行进行子集化,这些行取决于某些起点并通过某些公式递增。 例如,我创建了以下数据:

  Day =  seq(as.Date("2000-01-01"), length = 15, by = "days")              
  set.seed(123)
  df1 <- data.frame( rowid =  c(1:30),
               Category = c("ID1", "ID1","ID1", "ID1","ID1", "ID1","ID1", "ID1",  "ID1", "ID1","ID1", 
                      "ID1","ID1", "ID1", "ID2", "ID2","ID2", "ID2", "ID2", "ID2","ID2", "ID2", "ID2", "ID2",  "ID3", "ID3","ID3", "ID3", "ID3", "ID3"),
               Day =  rep(Day, 2),
               Var = sample(1:30, 30, TRUE) )
  df1

我有一个定义的起始位置,例如 start = 2。它代表每个 ID 相对于其类别的起始位置。 例如,ID1 开始 ar rowid=2,ID2 从 rowid=16 开始,ID3 从 rowid=26 开始。

我想为每个 ID 设置子集 - 从其起始位置开始 - 所有按如下方式递增的行:increment[i]= increment[i-1] + constant。 常数是一个常数,比如说 3。

输出应该是这样的:

  rowid     Category        Day       Var
    2       ID1         2000-01-02     19
    5       ID1         2000-01-05     10
    8       ID1         2000-01-08     11
    11      ID1         2000-01-11     14
    13      ID1         2000-01-13     25
    16      ID2         2000-01-01      5
    19      ID2         2000-01-04     25
    22      ID2         2000-01-07      9     
    26      ID3         2000-01-11     26
    29      ID3         2000-01-14      9

对此有任何帮助吗? 谢谢

【问题讨论】:

  • 我在理解您的逻辑时遇到了一些麻烦?请详细说明您的增量功能?在我看来,您似乎只想要从起点开始的每 3 个row,是吗?
  • 你是绝对正确的,我想要每个 ID 从起点开始的每第 n 行(第 3 行)
  • 结果中不应该是rowid == 14 而不是rowid == 13
  • 对,对不起,谢谢
  • @gogo88 - 如果以下答案之一对您有用,您能否接受它以便将其从未答复列表中删除?最好使该列表尽可能短:)

标签: r subset


【解决方案1】:

我们可以使用filter

library(dplyr)
df1 %>%
     group_by(Category) %>%
     filter(rep(c(FALSE, TRUE, FALSE), length.out = n()))

-输出

# A tibble: 10 x 4
# Groups:   Category [3]
   rowid Category Day          Var
   <int> <chr>    <date>     <int>
 1     2 ID1      2000-01-02    19
 2     5 ID1      2000-01-05    10
 3     8 ID1      2000-01-08    11
 4    11 ID1      2000-01-11    14
 5    14 ID1      2000-01-14    26
 6    16 ID2      2000-01-01     5
 7    19 ID2      2000-01-04    25
 8    22 ID2      2000-01-07     9
 9    26 ID3      2000-01-11    26
10    29 ID3      2000-01-14     9

【讨论】:

    【解决方案2】:

    您可以使用slice 创建一个序列并选择行。

    library(dplyr)
    df1 %>% group_by(Category) %>% slice(seq(2, n(), 3)) %>% ungroup
    
    #   rowid Category Day          Var
    #   <int> <chr>    <date>     <int>
    # 1     2 ID1      2000-01-02    19
    # 2     5 ID1      2000-01-05    10
    # 3     8 ID1      2000-01-08    11
    # 4    11 ID1      2000-01-11    14
    # 5    14 ID1      2000-01-14    26
    # 6    16 ID2      2000-01-01     5
    # 7    19 ID2      2000-01-04    25
    # 8    22 ID2      2000-01-07     9
    # 9    26 ID3      2000-01-11    26
    #10    29 ID3      2000-01-14     9
    

    【讨论】:

      【解决方案3】:

      你想要这个吗?

      > subset(df1, !!ave(rowid, Category, FUN = function(x) seq_along(x) %in% seq(2, length(x), 3)))
         rowid Category        Day Var
      2      2      ID1 2000-01-02  19
      5      5      ID1 2000-01-05  10
      8      8      ID1 2000-01-08  11
      11    11      ID1 2000-01-11  14
      14    14      ID1 2000-01-14  26
      16    16      ID2 2000-01-01   5
      19    19      ID2 2000-01-04  25
      22    22      ID2 2000-01-07   9
      26    26      ID3 2000-01-11  26
      29    29      ID3 2000-01-14   9
      

      【讨论】:

        【解决方案4】:

        一种方法是使用ave,我更新了一个只有FALSElogical 向量,并将seq 获得的位置设置为TRUE by Category 并使用结果到子集df1

        start <- 2
        constant <- 3
        
        df1[ave(logical(nrow(df1)), df1$Category, FUN=function(i) 
          `[<-`(i,seq(start, length(i), constant), TRUE)),]
           rowid Category        Day Var
        #2      2      ID1 2000-01-02  19
        #5      5      ID1 2000-01-05  10
        #8      8      ID1 2000-01-08  11
        #11    11      ID1 2000-01-11  14
        #14    14      ID1 2000-01-14  26
        #16    16      ID2 2000-01-01   5
        #19    19      ID2 2000-01-04  25
        #22    22      ID2 2000-01-07   9
        #26    26      ID3 2000-01-11  26
        #29    29      ID3 2000-01-14   9
        

        【讨论】:

          【解决方案5】:

          这是使用dplyr的解决方案

          library(dplyr)
          
          start <- 2
          increment <- 3
          
          df1 %>% 
            group_by(Category) %>% 
            filter((row_number() - start) %% increment == 0) %>% 
            ungroup()
          

          基本上,此代码将过滤器应用于各个类别,并保留由提供的增量和起始值指定的行。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-10-30
            • 1970-01-01
            • 2018-04-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多