当数据量很大时,dcast 无法转换字符列
dcast fails to cast character column when the data size is large
我正在使用 library(reshape2)
包中的 dcast
函数来转换一个简单的 table 三列
df = data.table(id = 1:1e6,
var = c('continent','subcontinent',...),
val = c('America','Caribbean',...)````
by dcast(df, id ~ var, value.var ='val')
并自动将值转换为计数,即
id continent subcontinent
1 1 1
2 1 1
但是,如果我将大小减少到 10000 行,它会正确输出
id continent subcontinent
1 America Caribbean
2 Europe West Europe
这是一个错误还是我需要以某种方式更改代码?请帮忙。谢谢!
我通过包含聚合函数找到了解决此问题的快速方法。它现在可以工作了,但我仍然不确定为什么 dcast
对于不同大小的数据表现不同。
dcast(df, id ~ var, value.var ='val', fun.aggregate =function(x) paste(x[1])
这可能是由重复条目引起的。
因此您可能在您的子集中无意中删除了重复的行条目。
使用具有重复条目的 DF 输出
df = data.table(id = c(1,2,3,4,2),
var = c('continent','subcontinent','continent','continent','subcontinent'),
val = c('America','Caribbean','Africa','Europe','Caribbean'))
dcast(df, id ~ var, value.var ='val')
Aggregate function missing, defaulting to 'length'
id continent subcontinent
1: 1 1 0
2: 2 0 2
3: 3 1 0
4: 4 1 0
Try unique()
如果重复项不重要,可能值得:
dcast(unique(df), id ~ var, value.var ='val')
id continent subcontinent
1: 1 America NA
2: 2 NA Caribbean
3: 3 Africa NA
4: 4 Europe NA
问题不在于数据集本身的大小,而在于整个数据集中出现重复条目。通过从完整数据集中选择较小的子集,有可能不包含重复项。
help("dcast", "data.table")
说:
When variable combinations in formula
doesn't identify a unique value in a cell, fun.aggregate
will have to be specified, which defaults to length
if unspecified.
如何在完整数据集中查找重复项
所有重复项都可以通过
来识别
cols <- c("id", "var")
df[duplicated(df, by = cols) | duplicated(df, by = cols, fromLast = TRUE)][
order(id)]
id var val
1: 1 subcontinent Caribbean
2: 1 subcontinent South America
请注意,我们正在寻找 id
和 var
中的重复项,因为这两个构成了重塑后的 单元格 ,即行和列结果。
为什么 unique()
不起作用
注意:这就是为什么简单地使用 unique(df)
不起作用的原因:
unique(df)
id var val
1: 1 continent America
2: 1 subcontinent Caribbean
3: 2 continent Europe
4: 2 subcontinent West Europe
5: 1 subcontinent South America
不删除任何行。因此,
dcast(unique(df), id ~ var, value.var = "val")
Aggregate function missing, defaulting to 'length'
id continent subcontinent
1: 1 1 2
2: 2 1 1
而
unique(df, by = cols)
id var val
1: 1 continent America
2: 1 subcontinent Caribbean
3: 2 continent Europe
4: 2 subcontinent West Europe
已删除 id == 1L
的重复项 var
。因此,
dcast(unique(df, by = cols), id ~ var, value.var = "val")
id continent subcontinent
1: 1 America Caribbean
2: 2 Europe West Europe
如何查找重复行的行号
OP 报告说,该问题仅出现在完整数据集上,而不出现在前 1e5
行的子集上。
重复条目的行索引可以通过
找到
which(duplicated(df, by = cols))
其中 returns 5
用于示例数据集。对于 OP 的完整数据集,我怀疑
min(which(duplicated(df, by = cols))) > 1e5
为真,即前 1e5 行中没有重复项。
如何在重复条目的情况下创建字符列
使用 fun.aggregate = function(x) paste(x[1L])
以及在 df
上应用 unique()
只是为了删除任何令人不安的重复项。重复项将被静默删除。
或者,toString()
可以用作显示重复条目的聚合函数:
dcast(df, id ~ var, toString, value.var = "val")
id continent subcontinent
1: 1 America Caribbean, South America
2: 2 Europe West Europe
数据
library(data.table)
df <- data.table(
id = c(1L, 1L, 2L, 2L, 1L),
var = c("continent", "subcontinent", "continent", "subcontinent", "subcontinent"),
val = c("America", "Caribbean", "Europe", "West Europe", "South America")
)
df
id var val
1: 1 continent America
2: 1 subcontinent Caribbean
3: 2 continent Europe
4: 2 subcontinent West Europe
5: 1 subcontinent South America
我正在使用 library(reshape2)
包中的 dcast
函数来转换一个简单的 table 三列
df = data.table(id = 1:1e6,
var = c('continent','subcontinent',...),
val = c('America','Caribbean',...)````
by dcast(df, id ~ var, value.var ='val')
并自动将值转换为计数,即
id continent subcontinent
1 1 1
2 1 1
但是,如果我将大小减少到 10000 行,它会正确输出
id continent subcontinent
1 America Caribbean
2 Europe West Europe
这是一个错误还是我需要以某种方式更改代码?请帮忙。谢谢!
我通过包含聚合函数找到了解决此问题的快速方法。它现在可以工作了,但我仍然不确定为什么 dcast
对于不同大小的数据表现不同。
dcast(df, id ~ var, value.var ='val', fun.aggregate =function(x) paste(x[1])
这可能是由重复条目引起的。
因此您可能在您的子集中无意中删除了重复的行条目。
使用具有重复条目的 DF 输出
df = data.table(id = c(1,2,3,4,2),
var = c('continent','subcontinent','continent','continent','subcontinent'),
val = c('America','Caribbean','Africa','Europe','Caribbean'))
dcast(df, id ~ var, value.var ='val')
Aggregate function missing, defaulting to 'length'
id continent subcontinent
1: 1 1 0
2: 2 0 2
3: 3 1 0
4: 4 1 0
Try unique()
如果重复项不重要,可能值得:
dcast(unique(df), id ~ var, value.var ='val')
id continent subcontinent
1: 1 America NA
2: 2 NA Caribbean
3: 3 Africa NA
4: 4 Europe NA
问题不在于数据集本身的大小,而在于整个数据集中出现重复条目。通过从完整数据集中选择较小的子集,有可能不包含重复项。
help("dcast", "data.table")
说:
When variable combinations in
formula
doesn't identify a unique value in a cell,fun.aggregate
will have to be specified, which defaults tolength
if unspecified.
如何在完整数据集中查找重复项
所有重复项都可以通过
来识别cols <- c("id", "var")
df[duplicated(df, by = cols) | duplicated(df, by = cols, fromLast = TRUE)][
order(id)]
id var val 1: 1 subcontinent Caribbean 2: 1 subcontinent South America
请注意,我们正在寻找 id
和 var
中的重复项,因为这两个构成了重塑后的 单元格 ,即行和列结果。
为什么 unique()
不起作用
注意:这就是为什么简单地使用 unique(df)
不起作用的原因:
unique(df)
id var val 1: 1 continent America 2: 1 subcontinent Caribbean 3: 2 continent Europe 4: 2 subcontinent West Europe 5: 1 subcontinent South America
不删除任何行。因此,
dcast(unique(df), id ~ var, value.var = "val")
Aggregate function missing, defaulting to 'length' id continent subcontinent 1: 1 1 2 2: 2 1 1
而
unique(df, by = cols)
id var val 1: 1 continent America 2: 1 subcontinent Caribbean 3: 2 continent Europe 4: 2 subcontinent West Europe
已删除 id == 1L
的重复项 var
。因此,
dcast(unique(df, by = cols), id ~ var, value.var = "val")
id continent subcontinent 1: 1 America Caribbean 2: 2 Europe West Europe
如何查找重复行的行号
OP 报告说,该问题仅出现在完整数据集上,而不出现在前 1e5
行的子集上。
重复条目的行索引可以通过
找到which(duplicated(df, by = cols))
其中 returns 5
用于示例数据集。对于 OP 的完整数据集,我怀疑
min(which(duplicated(df, by = cols))) > 1e5
为真,即前 1e5 行中没有重复项。
如何在重复条目的情况下创建字符列
fun.aggregate = function(x) paste(x[1L])
以及在 df
上应用 unique()
只是为了删除任何令人不安的重复项。重复项将被静默删除。
或者,toString()
可以用作显示重复条目的聚合函数:
dcast(df, id ~ var, toString, value.var = "val")
id continent subcontinent 1: 1 America Caribbean, South America 2: 2 Europe West Europe
数据
library(data.table)
df <- data.table(
id = c(1L, 1L, 2L, 2L, 1L),
var = c("continent", "subcontinent", "continent", "subcontinent", "subcontinent"),
val = c("America", "Caribbean", "Europe", "West Europe", "South America")
)
df
id var val 1: 1 continent America 2: 1 subcontinent Caribbean 3: 2 continent Europe 4: 2 subcontinent West Europe 5: 1 subcontinent South America