次のようなデータフレームがあります。
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
次のルールに基づく整数である新しい変数 を追加したい: a 0
if df$Logical
is TRUE
、または変数のすべての行で同じ整数であり、A
およそB
(C
それらは double であるため、浮動小数点誤差のマージン) と等しく、 から始まり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
あるために取得し、2 番目と 4 番目の行は変数であるために取得し、2 番目と 5 番目の行でもほぼ同じです。行 6は、次の一意の行であるため、 を取得します。に割り当てられた整数の順序は、を除いて無関係であることに注意してください。たとえば、行 2 と 4 は、この整数が の他のケースで一意である限り、割り当てることもできます。Logical
TRUE
1
A
B
C
3
D
0
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
}
}
しかし、これは大きなデータ フレームでは非常に遅くなります。