varias graficos graficas functions ejemplo data r dataframe apply

graficos - usar columnas mĂșltiples como variables con sapply



mapply in r (4)

Tengo un dataframe y me gustaría aplicar una función que tome los valores de tres columnas y calcule la diferencia mínima entre los tres valores.

#dataset df <- data.frame(a= sample(1:100, 10),b = sample(1:100, 10),c= sample(1:100, 10)) #function minimum_distance <- function(a,b,c) { dist1 <- abs(a-b) dist2 <- abs(a-c) dist3 <- abs(b-c) return(min(dist1,dist2,dist3)) }

Estoy buscando algo como:

df$distance <- sapply(df, function(x) minimum_distance(x$a,x$b,x$c) ) ## errormessage Error in x$a : $ operator is invalid for atomic vectors

Si bien puedo usar ddply:

df2 <- ddply(df,.(a),function(r) {data.frame(min_distance=minimum_distance(r$a,r$b, r$c))}, .drop=FALSE)

Esto no mantiene todas las columnas. ¿Alguna sugerencia?

Editar: terminé usando:

df$distance <- mapply(minimum_distance, df$a, df$b, df$c)


Es mejor escribir una función y luego usar mapply en los vectores:

f1 <- function(a,b,c){ d =abs(a-b) e =abs(b-c) f= abs(c-a) return(pmin(d,e,f)) } qq <- mapply(f1, df$a, df$b, df$c)


Pruebe mapply ():

qq <- mapply(minimum_distance, df$a, df$b, df$c)


Sé que esto ha sido respondido, pero en realidad tomaría un enfoque diferente que toma cualquier cantidad de columnas y es más generalizable usando un enfoque externo:

vdiff <- function(x){ y <- outer(x, x, "-") min(abs(y[lower.tri(y)])) } apply(df, 1, vdiff)

Creo que esto es un poco más limpio y flexible.

EDITAR: Según los comentarios de zach, propongo esta función más formalizada que también funciona en marcos de datos con columnas no numéricas, eliminándolos y actuando solo en las columnas numéricas.

cdif <- function(dataframe){ df <- dataframe[, sapply(dataframe, is.numeric)] vdiff <- function(x){ y <- outer(x, x, "-") min(abs(y[lower.tri(y)])) } return(apply(df, 1, vdiff)) } #TEST it out set.seed(10) (df <- data.frame(a = sample(1:100, 10), b = sample(1:100, 10), c = sample(1:100, 10), d = LETTERS[1:10])) cdif(df)


prueba esto:

do.call("mapply", c(list(minimum_distance), df))

pero puedes escribir una versión vectorizada:

pminimum_distance <- function(a,b,c) { dist1 <- abs(a-b) dist2 <- abs(a-c) dist3 <- abs(b-c) return(pmin(dist1,dist2,dist3)) } pminimum_distance(df$a, df$b, df$c) # or do.call("pminimum_distance", df)