具体回应最后一句话:“直接在原始数据上执行此操作有什么更有效和优雅的方法。”,碰巧的是data.table http://datatable.r-forge.r-project.org/为此有一个新功能。
install.packages("data.table", repos="http://R-Forge.R-project.org")
# Needs version 1.8.1 from R-Forge. Soon to be released to CRAN.
将您的数据放入DT
:
> DT[, countcat:=.N, by=list(country,category)] # add 'countcat' column
category country countcat
1: 1 RUS 3
2: 2 GER 1
3: 3 USA 2
4: 1 RUS 3
5: 1 USA 1
6: 1 RUS 3
7: 3 GER 1
8: 3 USA 2
9: 2 RUS 1
10: 2 USA 1
> DT[, weight:=countcat/.N, by=country] # add 'weight' column
category country countcat weight
1: 1 RUS 3 0.75
2: 2 GER 1 0.50
3: 3 USA 2 0.50
4: 1 RUS 3 0.75
5: 1 USA 1 0.25
6: 1 RUS 3 0.75
7: 3 GER 1 0.50
8: 3 USA 2 0.50
9: 2 RUS 1 0.25
10: 2 USA 1 0.25
:=
通过引用数据添加一列,是一个“旧”功能。新功能是它现在按组工作。.N
是保存每组中的行数的符号。
这些操作内存效率高,并且应该可以扩展到大数据;例如。,1e8
, 1e9
rows.
如果您不想包含中间列countcat
,然后将其删除即可。同样,这是一种高效的操作,无论表的大小如何(通过在内部移动指针),它都会立即起作用。
> DT[,countcat:=NULL] # remove 'countcat' column
category country weight
1: 1 RUS 0.75
2: 2 GER 0.50
3: 3 USA 0.50
4: 1 RUS 0.75
5: 1 USA 0.25
6: 1 RUS 0.75
7: 3 GER 0.50
8: 3 USA 0.50
9: 2 RUS 0.25
10: 2 USA 0.25
>