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
,它是一个基于以下规则的整数:a0
ifdf$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