Вопрос:
Я новичок в этом форуме. Я думаю, что-то вроде этого было задано раньше, но я не уверен, что это то, что я хочу.
У меня есть такая последовательность,
1 2 3 4 5 8 9 10 12 14 15 17 18 19
Итак, что я хочу сделать, это получить все числа, которые образуют серию, поскольку числа, принадлежащие этому множеству, должны иметь постоянную разницу с предыдущим элементом, а также минимальное количество элементов должно быть 3 в этом наборе,
т.е. я вижу, что (1,2,3,4,5) образует одну такую серию, в которой числа появляются после интервала 1, а общий размер этого множества равен 5, который удовлетворяет минимальным пороговым критериям. (1,3,5) образует один такой шаблон, в котором числа появляются после интервала 2.
(8,10,12,14) образует еще один такой шаблон с интервалом 2. Таким образом, как вы можете видеть, интервал повторения может быть любым.
Кроме того, для определенного набора я хочу его максимальный. Я не хочу, (8,10,12) (хотя он удовлетворяет минимальному порогу 3 и постоянной разности) в качестве выхода и только максимальной длины, которую я хочу, т. (8,10,12,14).
Аналогично, для (1,2,3,4,5) я не хочу (1,2,3) или (2,3,4,5) в качестве выходного сигнала, только МАКСИМАЛЬНАЯ ДЛИНА ОДИН Я ХОЧУ, т.е. (1,2,3,4,5).
Как я могу это сделать в R?
Изменение: То есть, я хочу, чтобы любой набор, который формирует базовую серию AP с любой разницей, однако общее значение должно быть больше 3 в этой серии, и оно должно быть максимальным.
Edit2: Я пытался использовать rle и acf в R, но это не полностью решает мою проблему.
Edit3: Когда я сделал acf, это в основном дало мне максимальную пиковую разницу, которую я мог бы использовать. Однако я хочу, чтобы все различия были возможны. Кроме того, rle просто отличается. Это дало мне самую длинную непрерывную последовательность подобных чисел. Кого нет в моем случае.
Ответ №1
Если вы ищете последовательности последовательных чисел, то cgwtools::seqle найдет их для вас таким же образом, как rle найдет последовательность повторяющихся значений.
В общем случае, в основном, любое подмножество ваших данных, которые образуют такую последовательность, например 8,10,12,14 вы цитируете, ваши критерии настолько общие, что их очень сложно удовлетворить. Вам нужно будет начинать с каждого элемента вашей серии и выполнять поиск в прямом направлении для x[j] +1, x[j]+2, x[j]+3… ad infinitum. Это предполагает использование некоторых древовидных алгоритмов.
Ответ №2
Здесь потенциальное решение – пусть и очень уродливое, неряшливое:
## arithSeq <- function(x=nSeq, minSize=4){ ## dx <- diff(x,lag=1) Runs <- rle(diff(x)) ## rLens <- Runs[[1]] rVals <- Runs[[2]] pStart <- c( rep(1,rLens[1]), rep(cumsum(1+rLens[-length(rLens)]),times=rLens[-1]) ) pEnd <- pStart + c( rep(rLens[1]-1, rLens[1]), rep(rLens[-1],times=rLens[-1]) ) pGrp <- rep(1:length(rLens),times=rLens) pLen <- rep(rLens, times=rLens) dAll <- data.frame( pStart=pStart, pEnd=pEnd, pGrp=pGrp, pLen=pLen, runVal=rep(rVals,rLens) ) ## dSub <- subset(dAll, pLen >= minSize — 1) ## uVals <- unique(dSub$runVal) ## maxSub <- subset(dSub, runVal==uVals[1]) maxLen <- max(maxSub$pLen) maxSub <- subset(maxSub, pLen==maxLen) ## if(length(uVals) > 1){ for(i in 2:length(uVals)){ iSub <- subset(dSub, runVal==uVals[i]) iMaxLen <- max(iSub$pLen) iSub <- subset(iSub, pLen==iMaxLen) maxSub <- rbind( maxSub, iSub) maxSub } ## } ## deDup <- maxSub[!duplicated(maxSub),] seqStarts <- as.numeric(rownames(deDup)) outList <- list(NULL); length(outList) <- nrow(deDup) for(i in 1:nrow(deDup)){ outList[[i]] <- list( Sequence = x[seqStarts[i]:(seqStarts[i]+deDup[i,»pLen»])], Length=deDup[i,»pLen»]+1, StartPosition=seqStarts[i], EndPosition=seqStarts[i]+deDup[i,»pLen»]) outList } ## return(outList) ## } ##
Таким образом, в этой функции могут быть улучшены определенные вещи – например, я допустил ошибку где-то при вычислении pStart и pEnd, начальных и конечных индексов данной арифметической последовательности, но так получилось, что истинные начальные позиции такие последовательности задаются как ряды одного из промежуточных кадров данных, так что это было хакерское решение. В любом случае, он принимает числовой вектор x и параметр минимальной длины, minSize. Он вернет список, содержащий информацию о последовательностях, соответствующих указанным выше критериям.
set.seed(1234) lSeq <- sample(1:25,100000,replace=TRUE) nSeq <- c(1:10,12,33,13:17,16:26) ## > arithSeq(nSeq) [[1]] [[1]]$Sequence [1] 16 17 18 19 20 21 22 23 24 25 26 [[1]]$Length [1] 11 [[1]]$StartPosition [1] 18 [[1]]$EndPosition [1] 28 ## > arithSeq(x=lSeq,minSize=5) [[1]] [[1]]$Sequence [1] 13 16 19 22 25 [[1]]$Length [1] 5 [[1]]$StartPosition [1] 12760 [[1]]$EndPosition [1] 12764 [[2]] [[2]]$Sequence [1] 11 13 15 17 19 [[2]]$Length [1] 5 [[2]]$StartPosition [1] 37988 [[2]]$EndPosition [1] 37992
Как я уже сказал, его неряшливый и неэлегантный, но он должен заставить вас начать.