【问题标题】:Counting successor combinations in a data.frame计算 data.frame 中的后继组合
【发布时间】:2018-07-11 23:55:33
【问题描述】:

我得到了一个类似于以下的data.frame

OBJECT ID   TASK
1           A
1           C
1           D
1           E
2           A
2           B
2           C
2           D
2           F

现在我想计算data.frame 中唯一的连续组合,以获得以下结果:

PREDECESSOR  SUCCESSOR  COUNT
A            C          1
C            D          2
D            E          1
A            B          1
B            C          1
D            F          1

我已经想办法在两个for 循环的帮助下提取连续的值,但是我在一个新的data.frame(或list)中的分配和计数任务失败了。

【问题讨论】:

  • 看看包igraph

标签: r dataframe counting


【解决方案1】:
aggregate(COUNT~.,
          data.frame(PREDECESSOR = head(df1$TASK, -1),
                     SUCCESSOR = tail(df1$TASK, -1),
                     COUNT = 1),
          length)
#  PREDECESSOR SUCCESSOR COUNT
#1           E         A     1
#2           A         B     1
#3           A         C     1
#4           B         C     1
#5           C         D     2
#6           D         E     1
#7           D         F     1

即使您想先split OBJECT.ID,也可以使用类似的方法

temp = do.call(rbind, lapply(split(df1, df1$OBJECT.ID), function(X){
    aggregate(COUNT~., data.frame(PREDECESSOR = head(X$TASK, -1),
                                  SUCCESSOR = tail(X$TASK, -1),
                                  COUNT = 1),
              length)
}))

aggregate(COUNT~., temp, length)
#  PREDECESSOR SUCCESSOR COUNT
#1           A         C     1
#2           B         C     1
#3           C         D     2
#4           D         E     1
#5           A         B     1
#6           D         F     1

数据

df1 = structure(list(OBJECT.ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L), TASK = c("A", "C", "D", "E", "A", "B", "C", "D", "F")), .Names = c("OBJECT.ID", 
"TASK"), class = "data.frame", row.names = c(NA, -9L))

【讨论】:

  • 非常好的解决方案!
  • 第二种方法正是我想要的。非常感谢您的快速回复!
【解决方案2】:

使用data.table的解决方案:

代码:

library(data.table)
setDT(df)
df[, TASK0 := shift(TASK), OBJECT]
df[!is.na(TASK0), .N, .(TASK, TASK0)][, .(
    COUNT = sum(N)), .(PREDECESSOR = TASK0, SUCCESSOR = TASK)]

结果:

   PREDECESSOR SUCCESSOR COUNT
1:           A         C     1
2:           C         D     2
3:           D         E     1
4:           A         B     1
5:           B         C     1
6:           D         F     1

解释:

  • setDT(df):把data.frame变成data.table对象
  • [, TASK0 := shift(TASK), OBJECT]:获取每个 OBJECT 的前一个字母
  • !is.na(TASK0):删除每个OBJECT 的第一行(他们没有PREDECESSOR
  • .N, .(TASK, TASK0):计算TASKTASK0(前面的字母组合)的出现次数
  • sum(N):总和计数

数据(df):

structure(list(OBJECT = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), 
    TASK = c("A", "C", "D", "E", "A", "B", "C", "D", "F")), .Names = c("OBJECT", 
"TASK"), row.names = c(NA, -9L), class = c("data.table", "data.frame"
))

【讨论】:

    【解决方案3】:

    只是为了获得计数,您可以使用以下两行代码:

    cc <- cbind(df$TASK,c(df$TASK[-1],"LAST"))
    table(paste(cc[,1],cc[2],sep="-"))
    

    结果是

    A-B  A-C  B-C  C-D  D-E  D-F  E-A F-LAST 
    1    1    1    2    1    1    1   1 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-17
      • 2016-01-08
      • 1970-01-01
      相关资源
      最近更新 更多