使用R data.table更容易计算条件比例?

时间:2017-06-28 11:50:43

标签: r data.table

我们假设我们有这个玩具示例:

library(data.table)
temp <- data.table(first=c("A", "A","A", "A","B","C","C"), 
   sec=c("X", "X","X", "Y","X",  "Z","Z"), stringsAsFactors = T))

first sec
  A   X
  A   X
  A   X
  A   Y
  B   X
  C   Z
  C   Z

我想得到第三栏,说明在第一列出现时组合发生的次数。

我必须通过以下方式使用data.table执行此操作:

temp[,N1:=.N,by=.(first, sec)]
temp[,N2:=.N,by=first]
temp[, prop := N1/N2]
temp[,c("N1","N2"):=NULL]


first sec prop
   A   X 0.75
   A   X 0.75
   A   X 0.75
   A   Y 0.25
   B   X 1.00
   C   Z 1.00
   C   Z 1.00

这意味着A,X发生了3次。 A发生了4次,因此AX在第一个字母为A的75%时间内发生。

这样做不容易吗?

有点

temp[,.N(first,sec)/.N(first)]

2 个答案:

答案 0 :(得分:3)

如何使用ave在每个第一级组内进行分组:

temp[, prop := ave(as.numeric(sec), sec, FUN = length) / .N, by = .(first)]
# > temp
#    first sec prop
# 1:     A   X 0.75
# 2:     A   X 0.75
# 3:     A   X 0.75
# 4:     A   Y 0.25
# 5:     B   X 1.00
# 6:     C   Z 1.00
# 7:     C   Z 1.00

灵感来自:https://stackoverflow.com/a/32003058/3926543

另一种方式:连锁命令:

temp[,N:=.N,by=.(first, sec)][, prop := N / .N, by = .(first)][, N := NULL]

firstsec有多个级别而temp有更多行时,

链接命令或OP问题中的解决方案将比ave解决方案更快。

答案 1 :(得分:2)

这是另一种选择。在我看来,这并不简单,但有点体现了你的想法。我们的想法是首先使用table计算sec的单独值,返回比例和sec的相应值,drop计数为0,然后将返回的data.table连接到原始值。

temp[temp[, {cnt=table(sec); .(sec=names(cnt), prop=c(cnt) / .N)}, by=first][prop > 0],
     on=c("first", "sec")]
   first sec prop
1:     A   X 0.75
2:     A   X 0.75
3:     A   X 0.75
4:     A   Y 0.25
5:     B   X 1.00
6:     C   Z 1.00
7:     C   Z 1.00