假设我们有这个玩具示例:
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
我想获得第三列,说明第一列发生在发生的组合的比例。
我必须使用数据进行。
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次,因此斧头发生了75%的时间,第一个字母为a。
不能更轻松吗?
有点
temp[,.N(first,sec)/.N(first)]
与 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]
当first
和sec
具有多个级别时,temp
有更多的行,链接命令或OP问题中的解决方案将比ave
解决方案更快。
这是一种替代方案。在我看来,这并不是简单,但是体现了您的想法。这个想法是在首次使用table
内计数SEC的单独值,返回比例和SEC的相应值,DROP计数为0,然后加入返回的数据。
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