【问题标题】:"dims [product 0] do not match the length of object" error in R when using daply for frequency counts使用 daply 进行频率计数时,R 中的“dims [产品 0] 与对象的长度不匹配”错误
【发布时间】:2013-01-29 05:25:12
【问题描述】:

我有一个如下所示的 data.frames 列表:

df=data.frame(
data_id=rep(LETTERS[1:10],each=1),
data_value=c(1,2,2,3,3,2,3,1,1,3))
df2=data.frame(
data_id=rep(LETTERS[1:10],each=1),
data_value=c(2,1,3,1,1,1,2,1,2,1))
df3=data.frame(
data_id=rep(LETTERS[1:10],each=1),
data_value=c(2,2,3,3,1,2,2,1,2,3))
df.list <- list(df, df2, df3)

单个 data.frame 如下所示:

         data_id    data_value
1        A          1
2        B          2
3        C          2
4        D          3
5        E          3
6        F          2
7        G          3
8        H          1
9        I          1
10       J          3

我想计算每个唯一值在 data_value 中出现的频率。我可以这样做:

for(i in 1:length(df.list)){
    daply(df.list[[i]], .(df.list[[i]]$data_value), nrow) -> freq
}

这给了我频率计数(在这种情况下只是最后一个,对于 df3):

1 2 3 
2 5 3 

我的实际数据集要大得多,所以我不能在这里发布。但是,它具有完全相同的结构。问题是,当我尝试获取实际数据集的频率计数时,我收到以下错误消息:

Error in dim(out_array) <- out_dim : dims [product 0] do not match the length of object [1]

谁能告诉我需要从哪里着手解决这个问题?我不明白 'dim()' 的来源和作用。非常感谢。

【问题讨论】:

  • 如果没有产生此错误的 data.set,很难说出原因。请提供一个可重现的例子。

标签: r dataframe plyr frequency


【解决方案1】:

您实际上可以做得更好,将 for 循环替换为 laply,这意味着输入是一个列表,输出是一个矩阵/数组。

o <- laply(df.list, function(x) {
    table(x$data_value)
})
> o
#      1 2 3
# [1,] 3 3 4
# [2,] 6 3 1
# [3,] 2 5 3

为了检查你的错误原因,当你尝试这个时会发生什么?

o <- llply(df.list, function(x) {
    table(x$data_value)
})

编辑:为了让错误更容易理解,让我们创建这个data.frame:

d1 <- data.frame(a=1:4)
d2 <- data.frame(a=1:5)
d3 <- data.frame(a=1:6)
d4 <- data.frame(a=1:7)

dl <- list(d1,d2,d3,d4)

现在运行laply:

laply(dl, function(x) table(x$a))
# Error: Results must have the same dimensions.

为什么?要看到这一点,让我们打印一下:

> laply(dl, function(x) print(table(x$a)))

# 1 2 3 4 
# 1 1 1 1 
# 
# 1 2 3 4 5 
# 1 1 1 1 1 
# 
# 1 2 3 4 5 6 
# 1 1 1 1 1 1 
# 
# 1 2 3 4 5 6 7 
# 1 1 1 1 1 1 1 

# Error: Results must have the same dimensions.

你看到问题了吗?每行中的元素数量不同。你不能有一个矩阵(除非你将那些元素较小的元素附加到等于行)。

改为使用列表,以便它们成为列表的元素,稍后可以使用[[number]] 语法访问。

llply(dl, function(x) table(x$a))

# [[1]]
# 
# 1 2 3 4 
# 1 1 1 1 
# 
# [[2]]
# 
# 1 2 3 4 5 
# 1 1 1 1 1 
# 
# [[3]]
# 
# 1 2 3 4 5 6 
# 1 1 1 1 1 1 
# 
# [[4]]
# 
# 1 2 3 4 5 6 7 
# 1 1 1 1 1 1 1 

希望这能解决问题。

【讨论】:

  • 谢谢阿伦!使用 laply() 的第一个选项会发生以下错误消息:错误:结果必须具有相同的维度。您使用 llply 的第二个选项会生成一个包含所需频率表的表列表!谢谢!
  • 也许 daply() 和 laply() 的问题在于,并非列表中包含的所有 data.frames 都具有相同的维度(列号都相同,但行号不同)?
  • 是的,这是因为矩阵应该始终具有相同数量的行/列。但是在您的实际数据中存在违反此规定的情况。可能有一些data.frames只有2个唯一值,有些有3个唯一值..等等..检查一下。 (我将编辑以使此评论更易于理解)
  • 我完全理解。愚蠢的错误,因为如果我对示例数据集使用了具有不同行长的 data.frames,我就会发现。我遗漏了导致问题的关键功能。谢谢你的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
相关资源
最近更新 更多