【问题标题】:cut with varied intervals?以不同的间隔切割?
【发布时间】:2013-08-30 17:18:33
【问题描述】:

我有一个包含两个变量的数据集,一个是分组变量,另一个是值。数据按每个组内的值排序。我想将值变量切割成每个组内的一个因子,并且小于 diff(10) 的间隔。也就是说,如果 diff(val)>=10,则会创建一个新级别。下面是一个演示数据,其中newgrp 是我想要的新变量。也许这里需要filter(),但我已经对它发呆了很长一段时间。有什么想法吗?

  grp val  newgrp
    a 101   1   
    a 101   1
    a 102   1       
    a 110   1
    a 111   2 <-- a new level is created since 111 - 101 > 9
    a 112   2
    a 148   3 <-- a new level is created sine 152 - 148 > 9,
    a 157   3
    a 158   4 <-- a new level is created since 158 - 148>9
    b   8   1 <-- levels start over for group b
    b   9   1
    b  12   1
    b  17   1
    b  18   2

【问题讨论】:

  • 那么一个 val 为 142 的人在 grp=="a" 中会有什么组呢? (我认为您没有明确定义拆分规则。)
  • 好的,我编辑了演示数据,希望现在可以理解了。
  • 这不是很像this question,得到了很好的 Rcpp 答案吗?

标签: r filter split cut


【解决方案1】:

编辑

我认为没有任何方法可以避免首先定义一个循环遍历每个向量的函数,因为每次遇到足够大的差异时都需要重置两个数字(“基数”和“新组”) .

NewGroup = function(x)
{
    base = x[1]
    new = 1
    newgrp = c()
    for(i in seq_along(x))
    {
        if (x[i] - base > 9)
        {
            base = x[i]
            new = new + 1
        }
        newgrp[i] <- new
    }
    return(newgrp)
}

dt[,newgrp:=NewGroup(val),by=grp]

    grp val newgrp
 1:   a 101      1
 2:   a 101      1
 3:   a 102      1
 4:   a 110      1
 5:   a 111      2
 6:   a 112      2
 7:   a 148      3
 8:   a 157      3
 9:   a 158      4
10:   b   8      1
11:   b   9      1
12:   b  12      1
13:   b  17      1
14:   b  18      2

【讨论】:

  • 感谢您的快速回复,先生。如果值有较大的飞跃,则除法可能无法正确计算水平。我编辑了演示数据,希望现在更清晰。
【解决方案2】:

你可以用这个:

do.call(rbind, by(yourdf, yourdf$grp, function(df) within(df, newgrp <- cumsum(c(1,diff(val))>9))))

yourdf 替换为您的数据框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-10
    • 2021-12-27
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多