dcast警告: 缺少聚合函数:默认使用长度。

31

我的 df 数据看起来像这样:

Id  Task Type    Freq  
3     1    A       2
3     1    B       3
3     2    A       3
3     2    B       0
4     1    A       3
4     1    B       3
4     2    A       1
4     2    B       3

我想按照ID重新组织并得到:

Id   A    B …  Z    
3    5    3      
4    4    6        

我试过:

df_wide <- dcast(df, Id + Task ~ Type, value.var="Freq")

并收到以下警告:

缺少聚合函数:默认使用长度

我不知道应该在 fun.aggregate 中放什么。问题出在哪里?


1
根据所示的示例,我没有收到任何警告。如果您有重复项,则可能需要创建一个序列列。 - akrun
3
如果你需要根据期望的输出结果来求和,则可以使用 dcast(df, Id~Type, value.var='Freq', sum) - akrun
谢谢Jaap!我不确定我完全理解了您的解释:我的前两列(Id和Task)需要从两行折叠为一行。这就是为什么我需要fun.aggregate函数吗?如果是这样-为什么是“sum”?我没有把它们加在一起。 - user3315563
你能具体说明在什么情况下收到警告信息吗?是在使用 dcast(df, Id ~ Type, value.var="Freq") 还是 dcast(df, Id + Task ~ Type, value.var="Freq") 时?我只在使用 dcast(df, Id ~ Type, value.var="Freq") 时收到警告(这是合理的,正如我在回答中所解释的那样)。 - Jaap
当我使用“dcast(df, Id + Task ~ Type, value.var="Freq")”时,会得到这个结果。 - user3315563
2个回答

39
你收到此警告的原因在于fun.aggregate的描述(参见?dcast):

如果变量无法为每个输出单元格标识单个观测值,则需要聚合函数。如果需要但未指定,将默认为长度(带有消息)。

因此,在宽数据框中一个位置上存在多个值时,需要使用聚合函数。

根据你的数据进行解释:

当你使用dcast(df, Id + Task ~ Type, value.var="Freq")时,会出现这种情况。

  Id Task A B
1  3    1 2 3
2  3    2 3 0
3  4    1 3 3
4  4    2 1 3

这是合适的,因为对于每个 IdTaskType 的组合,Freq 中只有一个值。但当你使用 dcast(df, Id ~ Type, value.var="Freq") 时,会得到以下结果(包括一条警告信息):

Aggregation function missing: defaulting to length
  Id A B
1  3 2 2
2  4 2 2

现在,回顾一下您数据的顶部部分:

Id  Task Type    Freq  
3     1    A       2
3     1    B       3
3     2    A       3
3     2    B       0

你可以看到这是为什么。对于每个IdType组合,Freq中有两个值(例如Id为3:A类型分别为23B类型分别为30),而在宽格式的数据框中,你只能为每个type的值放一个值。因此,dcast希望将这些值聚合成一个值。默认的聚合函数是length,但你可以使用其他聚合函数,比如summeansd或自定义函数,通过指定它们的fun.aggregate参数实现。

例如,使用fun.aggregate = sum,你会得到:

  Id A B
1  3 5 3
2  4 4 6

现在没有警告,因为dcast被告知当存在多个值时该做什么:返回这些值的总和。


1
很好的解释。你如何对字符进行聚合? - NelsonGon
8
@NelsonGon 对于你使用的字符,例如使用toString函数来聚合它们:dcast(df, Id ~ Type, value.var="Freq", fun.aggregate = toString)。或者你可以定义自己的聚合函数 - 例如:f.agg <- function(x) paste(x, collapse = "-") - 然后使用它:dcast(df, Id ~ Type, value.var="Freq", fun.aggregate = f.agg) - Jaap
但是你知道“length”是如何工作的吗?我的意思是,“fun.aggregate = length”是做什么的?我认为我收到这个警告是因为夏令时产生了重复值。 - PM0087
@PeyM87 它按组计算值。 - Jaap

0

fun.aggregatedcast 公式中,当 value.var 列内的不同值对应于出现在 LHS(例如 "Id")上的相同值或值的组合被公式 RHS 中的变量组合强制合并到一个单元格中时,是必需的。

dcast 中默认使用 length() 是有信息量的,因为它

  • 可能表明数据中存在耦合性,并且
  • 定位需要注意的 length > 1 情况。

更具信息量的是使用函数 list() 作为 fun.aggregate,因为它显示了每个情况中涉及的 value.var 值:

dcast(dt, Id ~ Type, fun.aggregate = list, value.var = 'Freq')

   Id   A   B
1:  3 2,3 3,0
2:  4 3,1 3,3

基本上,表格单元格的长度为1。因此,在dcast中的默认情况可以通过修改公式或者实现长度为1的汇总(聚合)来解决:操作符、自定义或可用函数在每种情况下都能给出长度为1的结果,并且适合于此目的。


这基本上和我的答案一样。那么,为什么要再次发布呢? - Jaap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接