para - poligono en r
La forma más rápida de encontrar el segundo(tercero...) valor más alto/más bajo en vector o columna (13)
R ofrece max y min, pero no veo una forma realmente rápida de encontrar el otro valor en el orden aparte de ordenar todo el vector y de elegir el valor x de este vector.
¿Hay una forma más rápida de obtener el segundo valor más alto (por ejemplo)?
Gracias
Alternativa un poco más lenta, solo para los registros:
x <- c(12.45,34,4,0,-234,45.6,4)
max( x[x!=max(x)] )
min( x[x!=min(x)] )
Aquí hay una manera fácil de encontrar los índices de N valores más pequeños / más grandes en un vector (Ejemplo para N = 3):
N <- 3
N más pequeño:
ndx <- order(x)[1:N]
N más grande:
ndx <- order(x, decreasing = T)[1:N]
Entonces puedes extraer los valores como:
x[ndx]
Cuando hace poco estaba buscando una función R que devuelva índices de N máx. / Min superior en un vector determinado, me sorprendió que no exista tal función.
Y esto es algo muy similar.
La solución de fuerza bruta que usa la función base :: order parece ser la más fácil.
topMaxUsingFullSort <- function(x, N) {
sort(x, decreasing = TRUE)[1:min(N, length(x))]
}
Pero no es el más rápido en caso de que su valor N sea relativamente pequeño en comparación con la longitud del vector x .
Por otro lado, si la N es realmente pequeña, puede usar la función base :: whichMax de forma iterativa y en cada iteración puede reemplazar el valor encontrado por -Inf
# the input vector ''x'' must not contain -Inf value
topMaxUsingWhichMax <- function(x, N) {
vals <- c()
for(i in 1:min(N, length(x))) {
idx <- which.max(x)
vals <- c(vals, x[idx]) # copy-on-modify (this is not an issue because idxs is relative small vector)
x[idx] <- -Inf # copy-on-modify (this is the issue because data vector could be huge)
}
vals
}
Creo que ve el problema, la naturaleza de copiar en la modificación de R. Entonces, esto funcionará mejor para N muy (muy) muy pequeño (1, 2, 3) pero se ralentizará rápidamente para valores de N más grandes. Y estás iterando sobre todos los elementos en vector x N veces.
Creo que la mejor solución en clean R es usar partial base :: sort .
topMaxUsingPartialSort <- function(x, N) {
N <- min(N, length(x))
x[x >= -sort(-x, partial=N)[N]][1:N]
}
Luego puede seleccionar el último ítem (Nth) del resultado de las funciones defiend arriba.
Nota: las funciones definidas anteriormente son solo ejemplos: si desea usarlas, debe verificar las entradas / cordura (por ejemplo, N> longitud (x) ).
Escribí un pequeño artículo sobre algo muy similar (obtener índices de los valores máximos N máx. / Mín. De un vector) en http://palusga.cz/?p=18 . Aquí puede encontrar algunos puntos de referencia de funciones similares que definí anteriormente.
Descubrí que eliminando primero el elemento máximo y luego hago otras carreras máximas a una velocidad comparable:
system.time({a=runif(1000000);m=max(a);i=which.max(a);b=a[-i];max(b)})
user system elapsed
0.092 0.000 0.659
system.time({a=runif(1000000);n=length(a);sort(a,partial=n-1)[n-1]})
user system elapsed
0.096 0.000 0.653
Envolví la respuesta de Rob en una función ligeramente más general, que se puede usar para encontrar el 2 °, 3 °, 4 ° (etc.) máx .:
maxN <- function(x, N=2){
len <- length(x)
if(N>len){
warning(''N greater than length(x). Setting N=length(x)'')
N <- length(x)
}
sort(x,partial=len-N+1)[len-N+1]
}
maxN(1:10)
Esto encontrará el índice del N-ésimo valor más pequeño o más grande en el vector numérico de entrada x. Establezca bottom = TRUE en los argumentos si quiere la N''th desde abajo, o bottom = FALSE si quiere la N''th desde la parte superior. N = 1 e inferior = VERDADERO es equivalente a which.min, N = 1 y bottom = FALSE es equivalente a which.max.
FindIndicesBottomTopN <- function(x=c(4,-2,5,-77,99),N=1,bottom=FALSE)
{
k1 <- rank(x)
if(bottom==TRUE){
Nindex <- which(k1==N)
Nindex <- Nindex[1]
}
if(bottom==FALSE){
Nindex <- which(k1==(length(x)+1-N))
Nindex <- Nindex[1]
}
return(Nindex)
}
Por enésimo valor más alto,
sort(x, TRUE)[n]
Puede identificar el siguiente valor más alto con cummax()
. Si desea la ubicación de cada nuevo valor más alto, por ejemplo, puede pasar su vector de valores cummax()
a la función diff()
para identificar las ubicaciones en las que cambió el valor de cummax()
. decir que tenemos el vector
v <- c(4,6,3,2,-5,6,8,12,16)
cummax(v) will give us the vector
4 6 6 6 6 6 8 12 16
Ahora, si quieres encontrar la ubicación de un cambio en cummax()
tienes muchas opciones, sign(diff(cummax(v)))
usar sign(diff(cummax(v)))
. Tienes que ajustar por el primer elemento perdido debido a diff()
. El código completo para el vector v
sería:
which(sign(diff(cummax(v)))==1)+1
Puede usar la palabra clave sort
como esta:
sort(unique(c))[1:N]
Ejemplo:
c <- c(4,2,44,2,1,45,34,2,4,22,244)
sort(unique(c), decreasing = TRUE)[1:5]
dará los primeros 5 números máximos.
dplyr tiene la función nth, donde el primer argumento es el vector y el segundo es el lugar que desea. Esto también sirve para repetir elementos. Por ejemplo:
x = c(1,2, 8, 16, 17, 20, 1, 20)
Encontrar el segundo valor más grande:
nth(unique(x),length(unique(x))-1)
[1] 17
head(sort(x),..)
o tail(sort(x),...)
debería funcionar
Usa el argumento partial
de sort()
. Por el segundo valor más alto:
n <- length(x)
sort(x,partial=n-1)[n-1]
topn = function(vector, n){
maxs=c()
ind=c()
for (i in 1:n){
biggest=match(max(vector), vector)
ind[i]=biggest
maxs[i]=max(vector)
vector=vector[-biggest]
}
mat=cbind(maxs, ind)
return(mat)
}
esta función devolverá una matriz con los n valores superiores y sus índices. Espero que ayude a VDevi-Chou