Das Hauptproblem ist, dass Sie die Behandlung x
als Array-ähnliches Objekt beim Indizieren. I.e. Sie verwenden x[row, col]
Indizierung, wo Sie x[element]
verwenden sollten.
Sie müssen auch beim Einfügen von Ergebnissen in df1$diff
indexieren. Und Sie haben die euklidische Abstandsgleichung falsch; Sie müssen die quadrierten Differenzen addieren, nicht subtrahieren.
df1 <- data.frame(list(x = 1:5, y = (1:5)^2, z = 6:10))
df1$diff <- NA
for (i in 2:nrow(df1)) {
df1$diff[i] <- with(df1, sqrt((x[i] - x[i-1])^2 +
(y[i] - y[i-1])^2 +
(z[i] - z[i-1])^2))
}
> df1
x y z diff
1 1 1 6 NA
2 2 4 7 3.316625
3 3 9 8 5.196152
4 4 16 9 7.141428
5 5 25 10 9.110434
Sie brauchen nicht die Schleife dafür aber können Sie auf R verlassen tun Element-für-Element-Operationen und damit dies in einem einzigen Schritt:
df1 <- data.frame(list(x = 1:5, y = (1:5)^2, z = 6:10))
df1$diff <- c(NA, sqrt(rowSums((df1[-1, 1:3] - df1[-5, 1:3])^2)))
df1
> df1
x y z diff
1 1 1 6 NA
2 2 4 7 3.316625
3 3 9 8 5.196152
4 4 16 9 7.141428
5 5 25 10 9.110434
Sie werden wahrscheinlich möchte dies mit df1
zu einer Matrix gezwungen, wenn Ihr echtes Problem groß ist, da Datenrahmen ziemlich langsam sind.
m1 <- as.matrix(df1[, 1:3])
m1 <- cbind(m1, diff = c(NA, sqrt(rowSums((m1[-1, 1:3] - m1[-5, 1:3])^2))))
> m1
x y z diff
[1,] 1 1 6 NA
[2,] 2 4 7 3.316625
[3,] 3 9 8 5.196152
[4,] 4 16 9 7.141428
[5,] 5 25 10 9.110434
Sie können diese in eine Funktion wickeln head()
und tail()
mit so müssen Sie do't kümmern, wie viele Zeilen der Originaldaten hat:
myEuc <- function(x) {
if (isdf <- is.data.frame(x)) {
x <- data.matrix(x)
}
dij <- c(NA, sqrt(rowSums((tail(x, -1) - head(x, -1))^2)))
x <- cbind(x, diff = dij)
if (isdf) {
x <- as.data.frame(x)
}
x
}
df1 <- data.frame(list(x = 1:5, y = (1:5)^2, z = 6:10))
myEuc(df1)
> myEuc(df1)
x y z diff
1 1 6 NA
[2,] 2 4 7 3.316625
[3,] 3 9 8 5.196152
[4,] 4 16 9 7.141428
[5,] 5 25 10 9.110434
Vielleicht 'sqrt (abs (Reduzieren ('-', lapply (df1, function (x) (x-lag (x, default = x [1]))^2))))' oder 'c (0, sqrt (abs (Reduce ('-', as.data.frame ((sapply (df1, diff))^2))))) ' – akrun