我正在使用包中的dcast
函数 library(reshape2)
来投射一个简单的三列表格
df = data.table(id = 1:1e6,
var = c('continent','subcontinent',...),
val = c('America','Caribbean',...)````
Run Code Online (Sandbox Code Playgroud)
bydcast(df, id ~ var, value.var ='val')
并自动将值转换为计数,即
id continent subcontinent
1 1 1
2 1 1
Run Code Online (Sandbox Code Playgroud)
但是,如果我将大小减少到 10000 行,它会正确输出
id continent subcontinent
1 America Caribbean
2 Europe West Europe
Run Code Online (Sandbox Code Playgroud)
这是一个错误还是我需要以某种方式更改代码?请帮忙。谢谢!
问题不在于数据集本身的大小,而在于完整数据集中出现重复条目。通过从完整数据集中挑选较小的子集,有可能不包含重复项。
help("dcast", "data.table")
说:
当变量组合
formula
不能标识单元格中的唯一值时,fun.aggregate
必须指定,length
如果未指定则默认为。
所有出现的重复都可以通过
cols <- c("id", "var")
df[duplicated(df, by = cols) | duplicated(df, by = cols, fromLast = TRUE)][
order(id)]
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)id var val 1: 1 subcontinent Caribbean 2: 1 subcontinent South America
请注意,我们正在寻找重复项id
,var
因为这两个构成了重塑结果的单元格,即行和列。
unique()
不起作用注意:这就是为什么简单地采取unique(df)
行不通的解释:
unique(df)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)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")
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)Aggregate function missing, defaulting to 'length' id continent subcontinent 1: 1 1 2 2: 2 1 1
然而
unique(df, by = cols)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)id var val 1: 1 continent America 2: 1 subcontinent Caribbean 3: 2 continent Europe 4: 2 subcontinent West Europe
去掉了重复var
的id == 1L
。最后,
dcast(unique(df, by = cols), id ~ var, value.var = "val")
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)id continent subcontinent 1: 1 America Caribbean 2: 2 Europe West Europe
OP 报告说该问题仅出现在完整数据集上,而不出现在第一1e5
行的子集上。
可以通过以下方式找到重复条目的行索引
which(duplicated(df, by = cols))
Run Code Online (Sandbox Code Playgroud)
它返回5
样本数据集。对于 OP 的完整数据集,我怀疑
min(which(duplicated(df, by = cols))) > 1e5
Run Code Online (Sandbox Code Playgroud)
为真,即前 1e5 行内没有重复项。
OP自己的方式使用fun.aggregate = function(x) paste(x[1L])
,以及应用unique()
上df
仅仅着眼于消除任何干扰副本。重复项将被悄悄删除。
或者,toString()
可以用作显示重复条目的聚合函数:
dcast(df, id ~ var, toString, value.var = "val")
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)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
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)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
归档时间: |
|
查看次数: |
1115 次 |
最近记录: |