我的表格如下所示 - 许多企业,他们可能参与的一些实践(P1 - P4)以及一个名为“Peer'这是一个分组列(是 - 对等,否 - 没有对等)。所有练习栏都是是/否:
Business P1 P2 P3 P4 Peer
a y n y n y
b n n y n n
c n y y n y
d y y y y n
e n n n y y
f n n n y n
g y y n n y
h n y n n n
i n n y n y
j y n y y n
k n y y y n
l n y y y n
m y n n n n
n n n n n y
o n y n n y
p y y n y n
q n n y y y
r n n y y n
s y y y n y
t n y y n y
u n n n n y
v y n n y n
w n y n y n
x n y n y y
y y n y n n
z n n y n y
我想从中实现的是一个汇总表,其中显示了以下内容,其中percentage
是已经采用这种做法的企业数量(实践==" y"):
Peer Practice percentage
y P1 30
y P2 40
y P3 33
y P4 90
n P1 20
n P2 30
n P3 11
n P4 75
注意我没有计算第二张表中的百分比,它们已经组成。
虽然我认为这应该可以通过data.table实现(this question特别相关),但我只能弄清楚在我看来创建这个表的过于精细的方法。 P1的例子:
首先,计算每种类别中出现的百分比:
P1Stats <- setDT(dtUptake)[order(Peer), .(P1 = unique(P1), percentage = 100 * tabulate(P1)/.N), by = Peer]
Peer P1 percentage
1: n n 53.84615
2: n y 46.15385
3: y y 76.92308
4: y n 23.07692
从结果中,只选择P1
的吸收行是&#34; y&#34;:
P1Stats <- P1Stats[P1=="y"]
Peer P1 percentage
1: n y 46.15385
2: y y 76.92308
将列P1
的名称更改为Practice
P1Stats <- P1Stats[, .(Peer, Practice = P1, percentage)]
Peer Practice percentage
1: n y 46.15385
2: y y 76.92308
将y
列中的Practice
值替换为练习名称P1
:
P1Stats[, Practice := "P1"]
Peer Practice percentage
1: n P1 46.15385
2: y P1 76.92308
然后,如果我为每个练习都执行此操作,我可以通过将它们全部拉到一起来创建最终表格。我知道我可以将这三个顶级步骤合并为一个,然后再执行更新过程:
P1Stats <- setDT(dtUptake)[order(Peer), .(P1 = unique(P1), percentage = 100 * tabulate(P1)/.N), by = Peer][P1=="y"][, .(Peer, Practice = P1, percentage)]
P1Stats[, Practice := "P1"]
然而,这仍然不是很优雅。我想知道是否有办法让这个过程更精简?
答案 0 :(得分:3)
使用melt
和data.table
&#39; by
参数,您可以实现这一目标。例如,假设您的原始data.table
位于变量dt
中:
dt2 = melt.data.table(dt, id.vars=c('Business', 'Peer'), variable.name='practice')
dt2[,.(percentage=sum(value=='y')/.N*100), by=c('Peer','practice')]
by
操作将对一列或一组列的值进行分组。由于原始数据具有用于分组的值(P1,P2,P3,P4)不在列值中,而是以不同的列名称进行扩展,因此melt
生成的长格式是可行的方法。 / p>