data.frame中的数字相等

时间:2012-10-25 11:45:00

标签: r dataframe plyr

我有一个如下所示的数据框:

df <- data.frame(
  Logical = c(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE),
  A = c(1,2,3,2,3,1),
  B = c(1,0.05,0.80,0.05,0.80,1),
  C = c(1,10.80,15,10.80,15,1))

看起来像:

  Logical A    B    C
1    TRUE 1 1.00  1.0
2   FALSE 2 0.05 10.8
3   FALSE 3 0.80 15.0
4   FALSE 2 0.05 10.8
5   FALSE 3 0.80 15.0
6   FALSE 1 1.00  1.0

我想添加一个新变量D,这是一个基于以下规则的整数:0如果df$LogicalTRUE,或整数对于ABC变量的所有变量都是相同的(因为它们是双精度的,因此在浮点误差范围内)相等,从{{开始1}}。

此处的预期输出:

1

第一行获得 Logical A B C D 1 TRUE 1 1.00 1.0 0 2 FALSE 2 0.05 10.8 1 3 FALSE 3 0.80 15.0 2 4 FALSE 2 0.05 10.8 1 5 FALSE 3 0.80 15.0 2 6 FALSE 1 1.00 1.0 3 因为0Logical,第二行获得TRUE,因为变量1A和{ {1}}大约相等,第二和第五行相同。第六行获得B,因为它是下一个唯一的行。请注意,C中分配的整数顺序与3除外无关。例如,第2行和第4行也可以分配D,只要此整数在0的其他情况下是唯一的。


我考虑过使用聚合函数。例如,使用2

D

有效,但我不确定这对浮点错误有多好(我想我可以在此调用之前对这里的值进行舍入,但它应该非常稳定)。使用循环很容易:

ddply

但对于较大的数据帧来说这是非常慢的。

1 个答案:

答案 0 :(得分:4)

根据Matthew Dowle在下面的评论,data.table可以对数值进行分组,以.Machine$double.eps^.5容差来区分它们。考虑到这一点,data.table解决方案应该有效:

library(data.table)

DT <- as.data.table(df)

DT[, D := 0]

.GRP <- 0

DT[!Logical, D := .GRP <- .GRP + 1, by = "A,B,C"]

#    Logical A    B    C foo D
# 1:    TRUE 1 1.00  1.0   1 0
# 2:   FALSE 2 0.05 10.8   2 1
# 3:   FALSE 3 0.80 15.0   3 2
# 4:   FALSE 2 0.05 10.8   4 1
# 5:   FALSE 3 0.80 15.0   5 2
# 6:   FALSE 1 1.00  1.0   6 3

正如Matthew Dowle写道here.GRP在data.table 1.8.3中实现,但我仍然使用1.8.2


评论后续跟进,这是1.8.2中的新闻项目。将添加到?data.table,谢谢你的突出显示!

  

现在允许在键和ad hoc中使用数字列(类型double)。     J()SJ()不再强制doubleintegeri加入专栏     数字类型的不匹配是默认强制匹配的     x的连接列的类型。 两个浮点值     被认为是相等的(通过分组和二进制搜索连接),如果他们的     默认情况下,差异在sqrt(.Machine $ double.eps)之内。见例子     在?unique.data.table。完成FR#951,#1609和#1075。这铺平了     使用double的其他原子类型的方式(例如POSIXctbit64)。     感谢Chris Neff进行beta测试并发现密钥问题     两个数字列(错误#2004),修复和测试添加。