data.frame中的行数相等

data.frame中的行数相等,r,dataframe,plyr,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)) 我想添加一个新变量,D,它是一个基于以下规则的整数:a0ifdf$Logical为TRUE,或者是一个整数,该整数对于近似为(因为它们是双精度的,所以

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

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))
我想添加一个新变量,
D
,它是一个基于以下规则的整数:a
0
if
df$Logical
TRUE
,或者是一个整数,该整数对于近似为(因为它们是双精度的,所以在浮点误差范围内)相等,从
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
,因为
逻辑
TRUE
,第二行和第四行得到
1
,因为变量
A
B
C
在那里大致相等,第二行和第五行相同。第六行得到
3
,因为它是下一个唯一的行。注意除了
0
之外,在
D
中分配的整数是不相关的。例如,第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
库(“plyr”)

df$foo根据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
库(data.table)

DT能否将列
A
B
C
转换为因子?对于样本数据集,这看起来是可以的(wrt浮点数公差问题)是的,这应该行得通。但是我不太理解关于
因子
的第一句话。
数据。表
内部有代码在机器公差范围内分组
列,将
保持为
。它不会转换为
字符
因子
,并且依赖于格式精度,就像base一样。参见
示例(unique.data.table)
了解
tan(pi(…)
示例。文档可以在
?数据表中更清楚地显示,
分组
列在机器公差范围内。它使用与
所有.equal
相同的公差,即
。机器$double.eps^0.5
@MatthewDowle,感谢您的澄清。
因子
东西有点多余从早期版本的答案中。我将在查看
示例(unique.data.table)
后澄清它。好的,很酷。我很惊讶
?data.table
中没有关于
双精度的分组公差,所以将在…@MatthewDowle中放入一些内容,再次感谢。(太棒了!)能够使用
列作为关键列,我会发现在
数据下有信息非常有用。表
提到公差(或者可能它在那里,我错过了它…)哦,这只是从1.8.2开始的新闻。我将添加该项作为编辑,并将添加到
数据。表
。。。
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
  }
}
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