我有一个看起来像这样的数据框:
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
。
这里的预期输出:
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
is TRUE
,第二行和第四行1
是因为变量A
,B
并且C
在那里近似相等,第二行和第五行相同。第六行得到 a 3
,因为它是下一个唯一的行。请注意,分配的整数顺序D
无关紧要,除了0
. 例如,也可以分配第 2 行和第 4 行2
,只要该整数在D
.
我考虑过使用聚合函数。例如使用ddply
:
library("plyr")
df$foo <- 1:nrow(df)
foo <- dlply(df,.(A,B,C),'[[',"foo")
df$D <- 0
for (i in 1:length(foo)) df$D[foo[[i]]] <- i
df$D[df$Logical] <- 0
有效,但我不确定这对浮点错误有多大影响(我想我可以在此调用之前对此处的值进行四舍五入,但它应该相当稳定)。使用循环很容易:
df$D <- 0
c <- 1
for (i in 1:nrow(df))
{
if (!isTRUE(df$Logical[i]) & df$D[i]==0)
{
par <- sapply(1:nrow(df),function(j)!df$Logical[j]&isTRUE(all.equal(unlist(df[j,c("A" ,"B", "C")]),unlist(df[i,c("A" ,"B", "C")]))))
df$D[par] <- c
c <- c+1
}
}
但这对于较大的数据帧来说非常慢。