从R中的一组重复序列创建单个序列

时间:2013-08-02 18:39:13

标签: r dataframe

我在 R 中有一个数据框,格式如下:

Day Agent Event ID
1   Paul  true  1
1   Mary  false 2
1   Mary  false 1
1   Paul  true  3
1   Steve true  1
2   Paul  true  1
2   Paul  false 1
2   Mary  true  1
2   Steve false 1

因此,对于每一天有人有事件(或没有),事件被记录为当天与ID相关的其他事件。该ID每天都会重置,因此第1天的ID 1与第2天的ID 1无关。我想要一个跨越多天的通用ID。所以我想添加一个如下列:

Day Agent Event ID UniID
1   Paul  true  1  1
1   Mary  false 2  2
1   Mary  false 1  1
1   Paul  true  3  2
1   Steve true  1  1
2   Paul  true  1  3
2   Paul  false 1  3
2   Mary  true  1  3
2   Steve false 1  2

UniID的目的是,如果我为某个人提取所有记录,我可以按顺序排列他们的事件,而不必担心这一天。知道如何去做吗?

更新:感谢目前为止的反馈。让我再次澄清一天/ ID / UniID。人们每天都会遇到或不会遇到事件(真/假)。真/假不影响他们是否获得身份证。当他们有机会参加活动时,他们将始终获得身份证。因此,在第1天,保罗经历了一次事件,并获得了身份证1,然后当天晚些时候他再次体验了身份并获得了身份证3,玛丽有两次机会并且没有经历任何时间并且收到身份证1和身份证2.身份证表示机会在某一天内体验活动。

由于ID甚至计数器每天都会重置,因此数据调整进入。所以在第2天,保罗再次体验了这一事件。然而它也被给予ID 1,但它与第1天的事件不同。所以我想给出一个跨越多天的序列顺序。

举一个不同的类比,将代理人视为棒球运动员,将事件视为本垒打的机会,以及作为比赛的日子。所以每个球员都有机会在每次击球时击中本垒打,并且我在击球时给这些比赛提供一个ID。现在我想带一个单独的球员,从最老到最新的命令,给他们一个新的身份证,涵盖他们整个职业生涯。

更新2:

Henrik的解决方案非常有效。他通过组合ID,Day,Agent创建一个唯一的字符串因子,然后计算唯一因子并输出计数作为新ID。感谢Henrik,通过对事件的混淆看到了很好的工作。下次我问这样的问题时,我会留下那些东西。

3 个答案:

答案 0 :(得分:1)

假设dat是您的原始data.frame,请尝试以下

  library(data.table)
  DT <- data.table(dat)

  DT[, uniID := seq(.N), by=list(Agent, Event)]
  DT

  #     Day Agent Event ID uniID
  #  1:   1  Paul  true  1     1
  #  2:   1  Mary false  2     1
  #  3:   1  Mary false  1     2
  #  4:   1  Paul  true  3     2
  #  5:   1 Steve  true  1     1
  #  6:   2  Paul  true  1     3
  #  7:   2  Paul false  1     1
  #  8:   2  Mary  true  1     1
  #  9:   2 Steve false  1     1

您不确定如何确定“唯一性”但无论您使用什么标准,请将其放在by=的列表中,然后您应该设置。

答案 1 :(得分:1)

不是很漂亮,但似乎有效:

library(plyr)
dd <- read.table(text = "Day Agent Event ID
1   Paul  true  1
1   Mary  false 2
1   Mary  false 1
1   Paul  true  3
1   Steve true  1
2   Paul  true  1
2   Paul  false 1
2   Mary  true  1
2   Steve false 1", header = TRUE)

dd$ID2 <- with(dd, paste0(Day, Agent, ID))

# for each agent, create a numeric version of its ID2    
dd <- ddply(.data = dd, .variables = .(Agent), mutate, UniID = as.numeric(as.factor(ID2)))

# some clean-up
dd2 <- subset(dd, select = -ID2)
arrange(dd2, Agent, Day, UniID)
PS:也许我误解了一些东西,但至少对我而言,你的虚拟数据中的Event变量引起了更多的混乱而不是帮助解决问题。

答案 2 :(得分:0)

ID必须是数字吗?它必须是连续的还是只是增加? 无论哪种方式,你似乎想要一个有序的序列。因此,首先按照您想要的方式订购数据,然后为每行添加一个ID。

library(data.table)

dd <- read.table(text = "Day Agent Event ID
1   Paul  true  1
1   Mary  false 2
1   Mary  false 1
1   Paul  true  3
1   Steve true  1
2   Paul  true  1
2   Paul  false 1
2   Mary  true  1
2   Steve false 1", header = TRUE)

dd <- dd[order(dd$Day,dd$Agent,dd$ID),]
dd$uniID <- seq(1:nrow(dd))

dd
  Day Agent Event ID uniID
3   1  Mary false  1     1
2   1  Mary false  2     2
1   1  Paul  true  1     3
4   1  Paul  true  3     4
5   1 Steve  true  1     5
8   2  Mary  true  1     6
6   2  Paul  true  1     7
7   2  Paul false  1     8
9   2 Steve false  1     9