I have this dataframe:
a <- c(2,5,90,77,56,65,85,75,12,24,52,32)
b <- c(45,78,98,55,63,12,23,38,75,68,99,73)
c <- c(77,85,3,22,4,69,86,39,78,36,96,11)
d <- c(52,68,4,25,79,120,97,20,7,19,37,67)
e <- c(14,73,91,87,94,38,1,685,47,102,666,74)
df <- data.frame(a,b,c,d,e)
and this script:
R <- Map(` `, list(1:3), 0:9)
cmin <- t(as.matrix(rep(NA, ncol(df))))
for (r in seq(R)) {
for (f in seq(ncol(df))) {
x <- df[R[[r]], f]
y <- df[R[[r]], -f]
dif_2 <- (x - y)^2
cmin[f] <- which.min(colSums(dif_2))
}
}
dif_3 <- as.matrix(dif_2[,cmin])
sq <- sqrt(dif_3)
How can I put the last two lines of the script into the "for" loop above?
Thanks everyone for helping me!
CodePudding user response:
If the output of 'sq' should be a vector
sq <- c()
for (r in seq(R)) {
for (f in seq(ncol(df))) {
x <- df[R[[r]], f]
y <- df[R[[r]], -f]
dif_2 <- (x - y)^2
cmin[f] <- which.min(colSums(dif_2))
dif_3 <- as.matrix(dif_2[,cmin[f]])
sq <- c(sq, sqrt(dif_3))
}
}
-output
> sq
[1] 12 68 1 31 5 7 25 17 1 25 17 1 31 5 7 68 1 10 5 7 32 17 1 3 17 1 3 5 7 32 8 22 7
[34] 8 22 7 1 3 75 1 3 75 1 10 38 10 38 27 32 31 26 55 52 4 52 23 55 10 38 27 52 4 1 31 26 22
[67] 52 4 1 23 55 12 31 26 22 4 1 36 57 63 1 4 1 36 51 11 19 27 84 610 12 55 5 63 1 3 63 1 3
[100] 12 55 5 84 610 35 55 5 5 1 3 32 1 3 32 55 5 5 610 35 78 5 5 15 3 32 3 3 32 3 5 5 15
[133] 28 34 567 5 15 35 32 3 62 12 44 21 5 15 35 34 567 1
If it should be a list
sq <- list()
for (r in seq(R)) {
for (f in seq(ncol(df))) {
x <- df[R[[r]], f]
y <- df[R[[r]], -f]
dif_2 <- (x - y)^2
cmin[f] <- which.min(colSums(dif_2))
dif_3 <- as.matrix(dif_2[,cmin[f]])
sq <- c(sq, list(sqrt(dif_3)))
}
}
sqmat <- do.call(cbind, sq)
CodePudding user response:
If I understand correctly, you want the min distances for each row indices given in R
. The code below creates two data structures, sq_list1
and sq_3d
that store the same values but one o them is a list of matrices and the other is a 3d array with the 3rd index 1:length(R)
.
sq_list <- replicate(length(R),
matrix(nrow = length(R[[1]]), ncol = ncol(df)),
simplify = FALSE)
sq_3d <- replicate(length(R),
matrix(nrow = length(R[[1]]), ncol = ncol(df)))
for (r in seq(R)) {
for (f in seq(ncol(df))) {
x <- df[R[[r]], f]
y <- df[R[[r]], -f]
dif_2 <- (x - y)^2
cmin <- which.min(colSums(dif_2))
dif_3 <- dif_2[, cmin]
sq_list[[r]][, f] <- sqrt(dif_3)
sq_3d[, f, r] <- sqrt(dif_3)
}
}
# output not shown
sq_list
sq_3d
Edit
This seems simpler.
faux <- function(r, df){
sub_df <- df[r, ]
sapply(seq(ncol(sub_df)), \(f){
d <- (sub_df[, f] - sub_df[, -f])^2
cmin <- which.min(colSums(d))
sqrt(d[, cmin])
})
}
sq_list2 <- lapply(R, faux, df = df)
identical(sq_list, sq_list2)
#[1] TRUE