给定下面的数据表,我怎样才能得到想要的结果?"grpFreq"列包含原始data.table中每个"grp"的计数,"posCnt"列包含每个组的"val"中的正数计数,"ratio"列是posCnt/grpFreq。
library( data.table )
DT <- data.table( grp = c(1,2,5,5,5,5,3,4,4,4), val = c(-1,0,1,1,-1,1,1,-1,-1,1) )
DT
grp val
1: 1 -1
2: 2 0
3: 5 1
4: 5 1
5: 5 -1
6: 5 1
7: 3 1
8: 4 -1
9: 4 -1
10: 4 1
对于此期望的结果:
# grp grpFreq posCnt ratio
# 1 1 0 0
# 2 1 0 0
# 3 1 1 1
# 4 3 1 0.33
# 5 4 3 0.75
以下尝试让我了解了一部分。首先,"val"列中值> 0 的计数位于最右侧的列中(不需要"-1"和"0"列(:
dcast(DT, grp~val, length)
grp -1 0 1
1: 1 1 0 0
2: 2 0 1 0
3: 3 0 0 1
4: 4 2 0 1
5: 5 1 0 3
其次,这让我得到了每个"grp"的频率计数,但形式与上面不同:
library(dplyr)
DT %>%
group_by(grp) %>%
mutate(count = n())
grp val count
(dbl) (dbl) (int)
1 1 -1 1
2 2 0 1
3 5 1 4
4 5 1 4
5 5 -1 4
6 5 1 4
7 3 1 1
8 4 -1 3
9 4 -1 3
10 4 1 3
有什么想法吗?非常感谢!!
在data.table
中,你可以做
DT[order(grp), .(grpFreq=.N, posCnt=sum(val > 0), ratio=sum(val > 0) / .N), by=grp]
在一次调用中或更好地使用链条和:=
DT[order(grp), .(grpFreq=.N, posCnt=sum(val > 0)), by=grp][, ratio := posCnt / grpFreq][]
第二种方法可能更可取,因为它减少了计算次数,并且使用:=
进行分配是内存效率高的。实际上,第二次调用结束时的[]
不是必需的,但告诉data.table
将结果打印到屏幕上。
两者都返回
grp grpFreq posCnt ratio
1: 1 1 0 0.0000000
2: 2 1 0 0.0000000
3: 3 1 1 1.0000000
4: 4 3 1 0.3333333
5: 5 4 3 0.7500000
DT <- data.table( grp = c(1,2,5,5,5,5,3,4,4,4), val = c(-1,0,1,1,-1,1,1,-1,-1,1) )
DT %>%
group_by(grp) %>%
summarize(grpFreq = length(grp),
posCnt = sum(val > 0)) %>%
mutate(ratio = posCnt/grpFreq)
# A tibble: 5 × 4
grp grpFreq posCnt ratio
<dbl> <int> <int> <dbl>
1 1 1 0 0.0000000
2 2 1 0 0.0000000
3 3 1 1 1.0000000
4 4 3 1 0.3333333
5 5 4 3 0.7500000