我有一个如下所示的数据框:
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$Logical
是TRUE
,或整数对于A
,B
和C
变量的所有变量都是相同的(因为它们是双精度的,因此在浮点误差范围内)相等,从{{开始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
因为0
为Logical
,第二行获得TRUE
,因为变量1
,A
和{ {1}}大约相等,第二和第五行相同。第六行获得B
,因为它是下一个唯一的行。请注意,C
中分配的整数顺序与3
除外无关。例如,第2行和第4行也可以分配D
,只要此整数在0
的其他情况下是唯一的。
我考虑过使用聚合函数。例如,使用2
:
D
有效,但我不确定这对浮点错误有多好(我想我可以在此调用之前对这里的值进行舍入,但它应该非常稳定)。使用循环很容易:
ddply
但对于较大的数据帧来说这是非常慢的。
答案 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()
不再强制double
到integer
。i
加入专栏 数字类型的不匹配是默认强制匹配的x
的连接列的类型。 两个浮点值 被认为是相等的(通过分组和二进制搜索连接),如果他们的 默认情况下,差异在sqrt(.Machine $ double.eps)之内。见例子 在?unique.data.table
。完成FR#951,#1609和#1075。这铺平了 使用double
的其他原子类型的方式(例如POSIXct
和bit64
)。 感谢Chris Neff进行beta测试并发现密钥问题 两个数字列(错误#2004),修复和测试添加。