Tôi đã bị tấn cùng một chức năng ít đệ quy đó sẽ tìm tất cả các bộ ba liên tiếp giữa nhiều vectơ khi bạn vượt qua nó (cần phải vượt qua ít nhất ba). Nó có lẽ là một chút thô, nhưng dường như làm việc.
Hàm sử dụng dấu ba chấm, ...
, để chuyển đối số. Do đó, sẽ cần nhiều đối số (ví dụ: vectơ số) mà bạn cung cấp và đặt chúng trong danh sách items
. Sau đó, giá trị nhỏ nhất trong mỗi vector được truyền đi, cùng với chỉ số của nó.
Sau đó, phân của các vectơ tương ứng với bộ ba nhỏ nhất được tạo và lặp lại thông qua sử dụng vòng lặp for()
, trong đó các giá trị đầu ra được chuyển đến vector đầu ra out
.Các vectơ đầu vào trong items
được cắt tỉa và truyền lại thành hàm theo kiểu đệ quy. Chỉ khi tất cả vectơ là NA
, nghĩa là không còn giá trị nào trong vectơ, hàm trả về kết quả cuối cùng.
library(magrittr)
# define function to find the triplets
tripl <- function(...){
items <- list(...)
# find the smallest number in each passed vector, along with its index
# output is a matrix of n-by-2, where n is the number of passed arguments
triplet.id <- lapply(items, function(x){
if(is.na(x) %>% prod) id <- c(NA, NA)
else id <- c(which(x == min(x)), x[which(x == min(x))])
}) %>% unlist %>% matrix(., ncol=2, byrow=T)
# find the smallest triplet from the passed vectors
index <- order(triplet.id[,2])[1:3]
# create empty vector for output
out <- vector()
# go through the smallest triplet's indices
for(i in index){
# .. append the coresponding item from the input vector to the out vector
# .. and remove the value from the input vector
if(length(items[[i]]) == 1) {
out <- append(out, items[[i]])
# .. if the input vector has no value left fill with NA
items[[i]] <- NA
}
else {
out <- append(out, items[[i]][triplet.id[i,1]])
items[[i]] <- items[[i]][-triplet.id[i,1]]
}
}
# recurse until all vectors are empty (NA)
if(!prod(unlist(is.na(items)))) out <- append(list(out),
do.call("tripl", c(items), quote = F))
else(out <- list(out))
# return result
return(out)
}
Chức năng có thể được gọi bằng cách truyền các vectơ đầu vào làm đối số.
# input vectors
a = c(3,5)
b = c(6,1,8,7)
c = c(4,2,9)
# find all the triplets using our function
y <- tripl(a,b,c)
Kết quả là danh sách chứa tất cả thông tin cần thiết, mặc dù không có thứ tự.
print(y)
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 4 5 6
#
# [[3]]
# [1] 7 9 NA
#
# [[4]]
# [1] 8 NA NA
đặt hàng tất cả mọi thứ có thể được thực hiện bằng sapply()
:
# put everything in order
sapply(y, function(x){x[order(x)]}) %>% t
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# [3,] 7 9 NA
# [4,] 8 NA NA
Có điều là, rằng nó sẽ chỉ sử dụng một giá trị mỗi vector để tìm ba. Do đó, sẽ không tìm thấy bộ ba liên tiếp c(6,7,8)
trong số các ví dụ: c(6,7,11)
, c(8,9,13)
và c(10,12,14)
. Trong trường hợp này, nó sẽ trả về c(6,8,10)
(xem bên dưới).
a<-c(6,7,11)
b<-c(8,9,13)
c<-c(10,12,14)
y <- tripl(a,b,c)
sapply(y, function(x){x[order(x)]}) %>% t
# [,1] [,2] [,3]
# [1,] 6 8 10
# [2,] 7 9 12
# [3,] 11 13 14
Mỗi phần tử trong một bộ ba phải đến từ các mảng khác nhau không? '{2,3,4} 'có được coi là một bộ ba hợp lệ không? – Psidom
Có! , {2,3,4}, {6,7,8} hoặc {7,8,9} không hợp lệ. –