vectores son saber perpendiculares paralelos paralelo paralelismo otro lineal encontrar como calcular r parallel-processing vectorization max minimum

son - ¿Hay un vector paralelo máximo() y mínimo()?



vectores paralelos algebra lineal (4)

Tengo un data.frame con las columnas "a" y "b". Quiero agregar columnas llamadas "alto" y "bajo" que contienen la más alta y la más baja entre las columnas a y b.

¿Hay una manera de hacer esto sin hacer un bucle sobre las líneas en el marco de datos?

edición: esto es para los datos de OHLC, por lo que la columna alta y baja debe contener el elemento más alto y el más bajo entre a y b en la misma línea, y no entre las columnas completas. Lo siento si esto está mal redactado.


Aquí hay una versión que implementé usando Rcpp . Comparé pmin con mi versión, y mi versión es aproximadamente 3 veces más rápida.

library(Rcpp) cppFunction(" NumericVector min_vec(NumericVector vec1, NumericVector vec2) { int n = vec1.size(); if(n != vec2.size()) return 0; else { NumericVector out(n); for(int i = 0; i < n; i++) { out[i] = std::min(vec1[i], vec2[i]); } return out; } } ") x1 <- rnorm(100000) y1 <- rnorm(100000) microbenchmark::microbenchmark(min_vec(x1, y1)) microbenchmark::microbenchmark(pmin(x1, y1)) x2 <- rnorm(500000) y2 <- rnorm(500000) microbenchmark::microbenchmark(min_vec(x2, y2)) microbenchmark::microbenchmark(pmin(x2, y2))

La salida de la función de microbenchmark para 100,000 elementos es:

> microbenchmark::microbenchmark(min_vec(x1, y1)) Unit: microseconds expr min lq mean median uq min_vec(x1, y1) 215.731 222.3705 230.7018 224.484 228.1115 max neval 284.631 100 > microbenchmark::microbenchmark(pmin(x1, y1)) Unit: microseconds expr min lq mean median uq max pmin(x1, y1) 891.486 904.7365 943.5884 922.899 954.873 1098.259 neval 100

Y por 500.000 elementos:

> microbenchmark::microbenchmark(min_vec(x2, y2)) Unit: milliseconds expr min lq mean median uq min_vec(x2, y2) 1.493136 2.008122 2.109541 2.140318 2.300022 max neval 2.97674 100 > microbenchmark::microbenchmark(pmin(x2, y2)) Unit: milliseconds expr min lq mean median uq pmin(x2, y2) 4.652925 5.146819 5.286951 5.264451 5.445638 max neval 6.639985 100

Así que puedes ver que la versión de Rcpp es más rápida.

Podría mejorarlo agregando algún control de errores en la función, por ejemplo: verifique que ambos vectores tengan la misma longitud, o que sean comparables (no carácter vs. numérico, o booleano vs. numérico).


Otra posible solución:

set.seed(21) Data <- data.frame(a=runif(10),b=runif(10)) Data$low <- apply(Data[,c("a","b")], 1, min) Data$high <- apply(Data[,c("a","b")], 1, max)


Parece que estás buscando pmax y pmin ("paralelo" max / min):

Extremes package:base R Documentation Maxima and Minima Description: Returns the (parallel) maxima and minima of the input values. Usage: max(..., na.rm = FALSE) min(..., na.rm = FALSE) pmax(..., na.rm = FALSE) pmin(..., na.rm = FALSE) pmax.int(..., na.rm = FALSE) pmin.int(..., na.rm = FALSE) Arguments: ...: numeric or character arguments (see Note). na.rm: a logical indicating whether missing values should be removed. Details: ‘pmax’ and ‘pmin’ take one or more vectors (or matrices) as arguments and return a single vector giving the ‘parallel’ maxima (or minima) of the vectors. The first element of the result is the maximum (minimum) of the first elements of all the arguments, the second element of the result is the maximum (minimum) of the second elements of all the arguments and so on. Shorter inputs are recycled if necessary. ‘attributes’ (such as ‘names’ or ‘dim’) are transferred from the first argument (if applicable).


Si su nombre data.frame es dat.

dat$pmin <- do.call(pmin,dat[c("a","b")]) dat$pmax <- do.call(pmax,dat[c("a","b")])