在dplyr中创建新的索引/重新索引

时间:2015-11-03 21:57:28

标签: r indexing dplyr data-manipulation

我在R中使用dplyr表。典型字段是主键,标识组的id号,日期字段和一些值。有些数字我做了一些操作,在一些初步步骤中抛出了大量数据。

为了进行分析的下一步(在MC Stan中),如果日期和组ID字段都是整数索引,则会更容易。所以基本上,我需要将它们重新索引为1之间的整数和不同元素的总数(对于group_id约为750,对于date_id约为250,group_id已经是整数,但日期不是)。将它导出到数据框后,这是相对简单的做法,但我很好奇是否可以在dplyr中。

我尝试创建一个新的date_val(名为date_val_new)如下。根据评论中的讨论,我有一些假数据。我有目的地使组和日期值不是1,但我没有把日期作为实际日期。我使数据不平衡,删除一些值来说明问题。无论date_val是什么,dplyr命令都会为每个新组重新启动索引为1。因此即使日期不同,每组也从1开始。

df1 <- data.frame(id = 1:40,
              group_id = (10 + rep(1:10, each = 4)),
              date_val = (20 + rep(rep(1:4), 10)),
              val = runif(40))
for (i in c(5, 17, 33))
{
    df1 <- df1[!df1$id == i, ]
}

df_new <- df1 %>%
            group_by(group_id) %>%
            arrange(date_val) %>%
            mutate(date_val_new=row_number(group_id)) %>%
            ungroup()

3 个答案:

答案 0 :(得分:7)

这是基本的R方法:

df1 %>% mutate(date_val_new = match(date_val, unique(date_val)))

或使用data.table,df1[, date_val_new := .GRP, by=date_val]

答案 1 :(得分:5)

使用group_indices_()为每个组生成唯一ID:

df1 %>% mutate(date_val_new = group_indices_(., .dots = "date_val"))

<强>更新

由于group_indices()无法处理课程tbl_postgres,您可以尝试dense_rank()

copy_to(my_db, df1, name = "df1")
tbl(my_db, "df1") %>% 
  mutate(date_val_new = dense_rank(date_val))

使用sql()

构建自定义查询
tbl(my_db, sql("SELECT *, 
               DENSE_RANK() OVER (ORDER BY date_val) AS DATE_VAL_NEW
               FROM df1"))

答案 2 :(得分:1)

或者,我认为您可以从getanID()包中尝试splitstackshape

library(splitstackshape)
getanID(df1, "group_id")[]

#    id group_id date_val        val .id
# 1:  1       11       21 0.01857242   1
# 2:  2       11       22 0.57124557   2
# 3:  3       11       23 0.54318903   3
# 4:  4       11       24 0.59555088   4
# 5:  6       12       22 0.63045007   1
# 6:  7       12       23 0.74571297   2
# 7:  8       12       24 0.88215668   3