Ich möchte sequential citation numbers für eine Zahl in R generieren. Die Zahlen sollten durch einen Bindestrich getrennt werden, wenn sie sequentiell sind. Ansonsten sind die Zahlen durch ein Komma getrennt. Zum Beispiel sollten die Nummern 1, 2, 3, 5, 6, 8, 9, 10, 11 and 13
als 1-3,5,6,8-11,13
ausgegeben werden.Sequentielle Zitation Nummerierung in R: separate Zahlen durch Bindestrich, wenn sequentiell - Komma hinzufügen, wenn nicht
Diese Frage wurde previously answered for c#, und ich habe eine Funktion geschrieben, die für R funktioniert, aber diese Funktion kann verbessert werden. Ich poste diese Frage als eine Referenz für andere, die ein ähnliches Bedürfnis haben könnten. Wenn Sie eine ähnliche Frage für R finden (was ich nicht getan habe), stimmen Sie bitte ab, um zu schließen, und ich werde die Frage entfernen.
Die folgende Funktion ist nicht sehr elegant, scheint aber die Aufgabe zu erfüllen. Wie kann man die Funktion kürzer und eleganter gestalten?
x <- c(1,2,3,5,6,8,9,10,11,13)
library(zoo) ## the function requires zoo::na.approx function
##' @title Generate hyphenated sequential citation from an integer vector
##' @param x integer vector giving citation or page numbers
##' @importFrom zoo na.approx
seq.citation <- function(x) {
## Result if lenght of the integer vector is 1.
if(length(x) == 1) return(x) else {
## Sort
x <- sort(x)
## Difference
df <- diff(x)
## Index to determine start and end points
ind <- c("start", rep("no", length(df)-1), "end")
ind[which(df > 1)] <- "end"
## Temporary start point vector
sts <- which(ind == "end") + 1
ind[sts[sts < length(ind)]] <- "start"
## Replace the first index element
ind[1] <- "start"
## Replace the last index element, if preceding one is "end"
if(ind[length(ind)-1] == "end") ind[length(ind)] <- "start"
## Groups for comma separation using "start" as the determining value.
grp <- rep(NA, length(x))
grp[which(ind == "start")] <- 1:length(grp[which(ind == "start")])
grp <- zoo::na.approx(grp, method = "constant", rule = 2)
## Split sequences by group
seqs <- split(x, grp)
seqs <- lapply(seqs, function(k) {
if(length(k) == 1) k else {
if(length(k) == 2) paste(k[1], k[2], sep = ",") else {
paste(k[1], k[length(k)], sep = "-")
}}
})
## Result
return(do.call("paste", c(seqs, sep = ",")))
}
}
seq.citation(x)
# [1] "1-3,5,6,8-11,13"
See, auch ein ähnliches [post] (https://stackoverflow.com/questions/34636461/function-to-summarize -vector-of-numbers-as-a-string) –