代码之家  ›  专栏  ›  技术社区  ›  Makaroni

从r中的当前数字开始,计数常量更大的数字

  •  -1
  • Makaroni  · 技术社区  · 5 年前

    想象一下,我有一个数字列表(即data.table/data.frame中的数字列)。

    1
    5
    5
    10
    11
    12
    

    对于列表中的每个数字,a想要计算有多少个唯一的数字 降低 而不是那个特定的数字+5。

    大写的解释,第一个数字=1,搜索范围为1+5=6,因此有三个数字在范围内,小于或等于: c(1,5,5) ,则计数唯一为2。 这一切都是通过假设我们有额外的条件,即数字不仅必须低于current_number+5,而且它在列表中的索引必须>=当前编号。

    在这种情况下,结果将是:

    2
    2
    2
    3
    2
    1
    

    注: 对于庞大的数据集,是否有快速的解决方案 数据帧 data.table ?我的数据集相当大,有10+M行。

    0 回复  |  直到 5 年前
        1
  •  7
  •   chinsoon12    5 年前

    我能想到的在R基中最快的方法(如果 x 已排序):

    findInterval(x + 5, unique(x)) - cumsum(!duplicated(x)) + 1L
    #[1] 2 2 2 3 2 1
    

    编辑:排序没有问题,因为 data.table ,对整数进行排序很简单:

    nr <- 1e7
    nn <- nr/2
    set.seed(0L)
    DT <- data.table(X=sample(nn, nr, TRUE))
    #DT <- data.table(X=c(1,5,5,10,11,12))
    
    system.time(
        DT[order(X), 
            COUNT := findInterval(X + 5L, unique(X)) - cumsum(!duplicated(X)) + 1L
        ]
    )
    #   user  system elapsed 
    #   1.73    0.17    1.53 
    

    2秒代表1000万行。

        2
  •  6
  •   zx8754    5 年前

    试试这个:

    x <- c(1,5,5,10,11,12)
    
    sapply(seq_along(x), function(i)
      sum(unique(x[i:length(x)]) <= (x[i] + 5)))
    # [1] 2 2 2 3 2 1
    
        3
  •  2
  •   IceCreamToucan    5 年前

    一种选择是使用sql自连接

    library(sqldf)
    
    
    df$r <- seq(nrow(df))
    
    sqldf('
    select    a.V1
              , count(distinct b.V1) as n
    from      df a
              left join df b
                on  b.V1 <= a.V1 + 5
                    and b.r >= a.r
    group by  a.r
    ')
    
    #   V1 n
    # 1  1 2
    # 2  5 2
    # 3  5 2
    # 4 10 3
    # 5 11 2
    # 6 12 1
    

    使用的数据:

    df <- structure(list(V1 = c(1L, 5L, 5L, 10L, 11L, 12L)), row.names = c(NA, 
    -6L), class = "data.frame")
    
        4
  •  0
  •   Georgery    5 年前
    sapply(yourVector + 5, function(x, y) sum(x > y), y = unique(x))
    
    推荐文章