Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R数据帧中应用按组计算_R_Aggregation_Data.table - Fatal编程技术网

在R数据帧中应用按组计算

在R数据帧中应用按组计算,r,aggregation,data.table,R,Aggregation,Data.table,我有这样的数据: object category country 495647 1 RUS 477462 2 GER 431567 3 USA 449136 1 RUS 367260 1 USA 495649 1 RUS 477461 2 GER 431562 3 USA 449133 2 RUS 367264 2 USA

我有这样的数据:

object category country
495647 1        RUS  
477462 2        GER  
431567 3        USA  
449136 1        RUS  
367260 1        USA  
495649 1        RUS  
477461 2        GER  
431562 3        USA  
449133 2        RUS  
367264 2        USA  
...
一个对象出现在不同的
(类别,国家)
对中,国家共享一个类别列表

我想在上面再加一列,这是每个国家的类别权重——一个类别中出现的对象数量,在一个国家内标准化为1(仅在唯一
(类别,国家)
对上求和)

我可以这样做:

aggregate(df$object, list(df$category, df$country), length)
然后从那里计算权重,但是直接在原始数据上进行计算更高效、更优雅的方法是什么呢

所需的示例输出:

object category country weight
495647 1        RUS     .75
477462 2        GER     .5 
431567 3        USA     .5 
449136 1        RUS     .75
367260 1        USA     .25
495649 1        RUS     .75
477461 3        GER     .5
431562 3        USA     .5
449133 2        RUS     .25
367264 2        USA     .25
...

上述内容将总结为一个国家内部的独特
(类别,国家)
对。

特别回应,并记住最后一句话:“直接在原始数据上做这件事更有效、更优雅的方式是什么?”,正好有了新的特点

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
是一个符号,用于保存每组中的行数

这些操作是内存有效的,应该扩展到大数据;e、 例如,
1e8
1e9

如果不希望包含中间列
countcat
,请在之后将其删除。同样,这是一个高效的操作,无论表的大小如何(通过在内部移动指针),它都能立即工作


我看不出一种易读的方法可以一行完成。但它可以非常紧凑

# Use table to get the counts.
counts <- table(df[,2:3])
# Normalize the table
weights <- t(t(counts)/colSums(counts))
# Use 'matrix' selection by names.
df$weight <- weights[as.matrix(df[,2:3])]
#使用表获取计数。
事实上,我不久前问过。对于这一点,data.table确实很好,尤其是现在实现了:=按组,并且不再需要自连接-如上所示。base R的最佳解决方案是
ave()
<代码>tapply()
也可以使用

这与上面的解决方案类似,使用
ave()
。但是,我强烈建议您查看data.table

df$count <- ave(x = df$object, df$country, df$category, FUN = length)
df$weight <- ave(x = df$count, df$country, FUN = function(x) x/length(x))

df$count可能属于StackOverflow,一些预期的输出数据会更好;e、 例如,澄清第1行和第4行的结果应均为50%还是均为100%。您直接根据原始数据要求按国家划分的类别权重,因此这似乎意味着后者?但在国内,它的总和不会是1,iiuc。谢谢Matthew,你说得很对-第1行和第4行的总和应该是100%(或1)。在一个国家内,权重总和应为1,仅考虑唯一(类别、国家)对-我正在编辑问题。这确实是一个优雅而有效的解决方案,谢谢!注意:我不熟悉
data.table
包,发现1./R-project.org存储库要求R>2.15和2./DT必须是
data.table
——因此我必须在原始数据框架上执行
DT=data.table(DT)
。作为data.table的不经常使用者,我有时会被完成事情的不同方式弄糊涂,我经常不得不去查阅资料。有没有计划建立一个更全面的文档,以取代目前构成小插曲的常见问题?@ilprincipe我知道你的意思,完全同意。虽然没有计划,因为我们不知道它应该是什么样子!你想要什么?有常见用例的wiki会好吗?如果您能提供所需的帮助,我们将不胜感激。如果你能画出或者开始你想要的格式,我很乐意填写。现有data.table wiki上的新页面?其他地方?Wiki格式还是可以复制的?在这方面我们需要帮助和指导。“即使是你们所看到的一系列常见的习语,也将是一个很好的开始。”尼古拉抱歉,我应该向你们提到这一点。干得不错。顺便说一句,
as.data.table
的转换速度通常比
data.table
快,但是为了方便起见,我们会对其进行更改,这样您就不需要知道了。或者从
data.table
开始。我想Wiki格式的扩展是可取的。作为第一步,它可以是一个列出所有习惯用法的唯一地址,以及一个大致完整的常见用例列表。一个合适的渐晕图/介绍应该更多地关注于介绍data.table及其本身的使用,并在较小程度上关注其与数据帧和计算速度的比较。我知道速度是一个卖点,但它应该分开更多。不管怎么说,大多数用户很快就会明白这一点。我觉得我对data.table还不够熟悉,还没有做出太多贡献,但我会考虑更多。
df$count <- ave(x = df$object, df$country, df$category, FUN = length)
df$weight <- ave(x = df$count, df$country, FUN = function(x) x/length(x))