R矢量化数据帧中的行编号

时间:2014-10-13 14:27:22

标签: r

我有一个由大量相关记录组成的大型有序数据框。对于每组相关记录,我需要将它们从1编号到相关记录的总数。如果我遍历整个数据帧,则操作时间过长。

我想知道是否有矢量化的方法来做到这一点?

例如,如果我有这个数据帧:

ID  Month    State
1   Apr-2014  AL
2   May-2014  AL
3   Jun-2014  AL
4   Apr-2014  MN
5   May-2014  MN
6   Apr-2014  FL
7   May-2014  FL

我想结束:

ID  Month    State  Seq
1   Apr-2014  AL    1
2   May-2014  AL    2
3   Jun-2014  AL    3
4   Apr-2014  MN    1
5   May-2014  MN    2
6   Apr-2014  FL    1
7   May-2014  FL    2

2 个答案:

答案 0 :(得分:4)

使用示例数据集。如果对数据集进行了排序,则可以将前一行Month与当前行进行比较,并检查它们是否不同。在下面的代码中,我删除了第一个观察df$Month[-1],并将最后一个观察结果与df$Month[-nrow(df)]进行了比较,以便lengths相等。通过使用!=,我们可以获得不同值的TRUE。在开头与TRUE连接并执行cumsum以获取index

 df$Seq <- cumsum(c(TRUE,df$Month[-1]!= df$Month[-nrow(df)]))
 df
 #  ID    Month State Seq
 #1  1 Apr-2014    AL   1
 #2  2 Apr-2014    MN   1
 #3  3 Apr-2014    FL   1
 #4  4 May-2014    AL   2
 #5  5 May-2014    MN   2
 #6  6 May-2014    FL   2
 #7  7 Jun-2014    AL   3

或者您可以将Month列转换为factor并将其重新转换回numeric

 as.numeric(factor(df$Month, levels=unique(df$Month)))
 #[1] 1 1 1 2 2 2 3

或使用data.table

 library(data.table)
  DT <- setDT(df)[, Seq:= .GRP, by=Month]
  DT
  #   ID    Month State Seq
  #1:  1 Apr-2014    AL   1
  #2:  2 Apr-2014    MN   1
  #3:  3 Apr-2014    FL   1
  #4:  4 May-2014    AL   2
  #5:  5 May-2014    MN   2
  #6:  6 May-2014    FL   2
  #7:  7 Jun-2014    AL   3

.GRP是一个特殊变量。请查看?data.table以了解更多信息。

数据

 df <-  structure(list(ID = 1:7, Month = c("Apr-2014", "Apr-2014", "Apr-2014", 
"May-2014", "May-2014", "May-2014", "Jun-2014"), State = c("AL", 
 "MN", "FL", "AL", "MN", "FL", "AL")), .Names = c("ID", "Month", 
 "State"), class = "data.frame", row.names = c(NA, -7L))

答案 1 :(得分:1)

如果您不关心实际的序号,您可以这样做:

df$Seq <- as.numeric(as.factor(df$Month))
df
#   ID    Month State Seq
# 1  1 Apr-2014    AL   1
# 2  2 Apr-2014    MN   1
# 3  3 Apr-2014    FL   1
# 4  4 May-2014    AL   3
# 5  5 May-2014    MN   3
# 6  6 May-2014    FL   3
# 7  7 Jun-2014    AL   2

如果你关心Seq中的实际数字(即它是有序的),你应该使用类似的东西:

month <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
df$part1 <- with(df, factor(gsub("([^\\-]*).*", "\\1", Month), month))
df$part2 <- with(df, factor(gsub("[^\\-]*\\-(.*)", "\\1", Month)))
df$whole <- with(df, interaction(part1, part2, drop = TRUE, lex.order = FALSE))
df$Seq <- as.numeric(df$whole)
#   ID    Month State part1 part2    whole Seq
# 1  1 Apr-2014    AL   Apr  2014 Apr.2014   1
# 2  2 Apr-2014    MN   Apr  2014 Apr.2014   1
# 3  3 Apr-2014    FL   Apr  2014 Apr.2014   1
# 4  4 May-2014    AL   May  2014 May.2014   2
# 5  5 May-2014    MN   May  2014 May.2014   2
# 6  6 May-2014    FL   May  2014 May.2014   2
# 7  7 Jun-2014    AL   Jun  2014 Jun.2014   3