根据行名

时间:2015-09-09 18:47:12

标签: r function

我有一个带有名称列和日期列的数据框(我已将其转换为自最早日期以来的天数)。我想要一个新列,记录该列名称在过去10天内的条目数。例如,这是一个当前数据框:

> head(starts[,c(5,29)], n=10)
    name            date_num
1   James           2
2   James           3
3   James           4
4   James           5
5   Julia           1
6   Julia           2
7   Julia           3
8   Julia           4
9   Jess            2
10  Jess            4

这就是我要找的东西:

> head(starts[,c(5,29)], n=10)
    name            date_num  count
1   James           2         0
2   James           3         1
3   James           4         2
4   James           5         3
5   Julia           1         0
6   Julia           2         1
7   Julia           3         2
8   Julia           4         3
9   Jess            2         0
10  Jess            4         1

这很简单,但希望我想要的是明确的。谢谢你的帮助! 编辑:根据前几个答案,我认为我不够清楚。我不是要为每个单独的名称添加索引列(认为它看起来可能类似);我想要计算具有相同名称的行数和在x-10和x之间的date_num值,其中x是所讨论行的date_num。这是一个更长的数据框,希望能提供更多信息:

> head(starts[,c(5,29)], n=10)
    name            date_num  count
1   James           1         0
2   James           2         1
3   James           3         2
4   James           4         3
5   James           5         4
6   James           7         5
7   James           8         6
8   James           9         7
9   James           10        8
10  James           11        9
11  James           12        9
12  James           13        9
13  James           15        8
14  Julia           1         0
15  Julia           2         1
16  Julia           4         2
17  Julia           19        0
18  Julia           20        1
19  Julia           22        2
20  Julia           24        3
21  Julia           31        2

希望这更有意义。计数仅包含10天前或更少且具有相同名称的行,而不是所有前面的行。我可以描述但不是代码的一种方法是:对于给定的行,取date_num,减去10,并找到具有相同名称且最小date_num大于该数字的行。取两行的索引号之间的差异。这需要一些排序和索引,但似乎可行。如果有人能描述一种方法让R做到这一点,我将非常感激。

2 个答案:

答案 0 :(得分:2)

您可以从我的“splitstackshape”软件包中尝试getanID

> library(splitstackshape)
> getanID(mydf, "name")[, .id := .id - 1][]
     name date_num .id
 1: James        2   0
 2: James        3   1
 3: James        4   2
 4: James        5   3
 5: Julia        1   0
 6: Julia        2   1
 7: Julia        3   2
 8: Julia        4   3
 9:  Jess        2   0
10:  Jess        4   1

.id := .id - 1是让计数从零开始。

这非常像:

library(data.table)
as.data.table(mydf)[, count := 0:(.N-1), by = name][]

答案 1 :(得分:0)

  

基础套餐:

  • 使用rle
  • df$count <- unlist(sapply(rle(df$name)$lengths, seq))-1
    

  • 将Marek的answer修改为从零开始:
  • df$count <- ave(rep(NA, nrow(df)), df$name, FUN=seq_along)-1
    
      

    sqldf

    library(sqldf)
    sqldf("SELECT a.name, a.date_num, COUNT(*)-1 As count
          FROM df AS a INNER JOIN df As b
          ON (a.name = b.name) AND (a.rowid >= b.rowid)
          GROUP BY a.name, a.date_num")
    

    <强>输出

        name date_num count
    1  James        2     0
    2  James        3     1
    3  James        4     2
    4  James        5     3
    5  Julia        1     0
    6  Julia        2     1
    7  Julia        3     2
    8  Julia        4     3
    9   Jess        2     0
    10  Jess        4     1
    

    数据

    df <- structure(list(name = c("James", "James", "James", "James", "Julia", 
         "Julia", "Julia", "Julia", "Jess", "Jess"), date_num = c(2L, 
          3L, 4L, 5L, 1L, 2L, 3L, 4L, 2L, 4L)), .Names = c("name", "date_num"), 
          class = "data.frame", row.names = c(NA, -10L))