在尝试使用aggregate
进行另一个问题here时,我遇到了一个相当奇怪的结果。我无法弄清楚为什么,我想知道我在做什么是完全错误的。
假设我有data.frame
这样:
df <- structure(list(V1 = c(1L, 2L, 1L, 2L, 3L, 1L),
V2 = c(2L, 3L, 2L, 3L, 4L, 2L),
V3 = c(3L, 4L, 3L, 4L, 5L, 3L),
V4 = c(4L, 5L, 4L, 5L, 6L, 4L)),
.Names = c("V1", "V2", "V3", "V4"),
row.names = c(NA, -6L), class = "data.frame")
> df
# V1 V2 V3 V4
# 1 1 2 3 4
# 2 2 3 4 5
# 3 1 2 3 4
# 4 2 3 4 5
# 5 3 4 5 6
# 6 1 2 3 4
现在,如果我想输出带有唯一行的data.frame
,并在df
中添加一列表示其频率。对于这个例子,
# V1 V2 V3 V4 x
# 1 1 2 3 4 3
# 2 2 3 4 5 2
# 3 3 4 5 6 1
我使用aggregate
通过如下实验获得此输出:
> aggregate(do.call(paste, df), by=df, print)
# [1] "1 2 3 4" "1 2 3 4" "1 2 3 4"
# [1] "2 3 4 5" "2 3 4 5"
# [1] "3 4 5 6"
# V1 V2 V3 V4 x
# 1 1 2 3 4 1 2 3 4, 1 2 3 4, 1 2 3 4
# 2 2 3 4 5 2 3 4 5, 2 3 4 5
# 3 3 4 5 6 3 4 5 6
所以,这给了我粘贴的字符串。所以,如果我使用length
而不是print
,它应该给我这些事件的数量,这是期望的结果,就是这种情况(如下所示)。
> aggregate(do.call(paste, df), by=df, length)
# V1 V2 V3 V4 x
# 1 1 2 3 4 3
# 2 2 3 4 5 2
# 3 3 4 5 6 1
这似乎有效。但是,当data.frame
维度为4 * 2500时,输出data.frame
为1 * 2501而不是4 * 2501(所有行都是唯一的,因此频率为1)。
> df <- as.data.frame(matrix(sample(1:3, 1e4, replace = TRUE), nrow=4))
> o <- aggregate(do.call(paste, df), by=df, length)
> dim(o)
# [1] 1 2501
我使用只有唯一行的较小data.frames进行测试,并提供正确的输出(例如,更改nrow=40
)。但是,当矩阵的尺寸增加时,这似乎不起作用。而我无法弄清楚出了什么问题!有什么想法吗?
答案 0 :(得分:10)
此处的问题是aggregate.data.frame()
如何确定群组。
在aggregate.data.frame()
中,有一个循环形成分组变量grp
。在该循环中,grp
通过以下方式更改/更新:
grp <- grp * nlevels(ind) + (as.integer(ind) - 1L)
您的示例的问题是,如果将by
转换为因素,并且循环已超过所有这些因素,则在您的示例grp
中最终会出现问题:
Browse[2]> grp
[1] Inf Inf Inf Inf
基本上,循环更新会将grp
的值推送到与Inf
无法区分的数字。
完成后,aggregate.data.frame()
稍后执行此操作
y <- y[match(sort(unique(grp)), grp, 0L), , drop = FALSE]
这就是早期问题现在表现为
的地方dim(y[match(sort(unique(grp)), grp, 0L), , drop = FALSE])
,因为
match(sort(unique(grp)), grp, 0L)
显然只返回1
:
> match(sort(unique(grp)), grp, 0L)
[1] 1
因为grp
只有一个唯一值。