dcast data r data.table

data - dcast r



Redondeo de columnas seleccionadas de data.table en R (6)

Creo que a partir de las soluciones, la de Steven Baupre que usa dplyr es la más elegante y aplicable de forma selectiva en diferentes columnas en un marco de datos, especialmente en física computacional.

> whatever <- setcolorder(dt_round, names(dt)) > whatever # names general picture blocks maze reading vocab #1: general 24.641 5.991 33.5 6.0 20.755 29.701 #2: picture 5.991 6.700 18.1 1.8 4.936 7.204 #3: blocks 33.520 18.137 149.8 19.4 31.430 50.753 #4: maze 6.023 1.782 19.4 12.7 4.757 9.075 #5: reading 20.755 4.936 31.4 4.8 52.604 66.762 #6: vocab 29.701 7.204 50.8 9.1 66.762 135.292

Como puede ver, la presión y la temperatura se redondearán a 0 decimales; Presión y temperatura pseudo-reducidas a 2 decs. y finalmente, presión y temperatura pseudo-críticas hasta 1 decimales.

Tengo los siguientes datos y código para redondear las columnas seleccionadas de estos datos.

> dput(mydf) structure(list(vnum1 = c(0.590165705411504, -1.39939534199836, 0.720226053660755, -0.253198380120377, -0.783366825121657), vnum2 = c(0.706508400384337, 0.526770398486406, 0.863136084517464, 0.838245498016477, 0.556775856064633 ), vch1 = structure(c(2L, 4L, 1L, 3L, 3L), .Label = c("A", "B", "C", "E"), class = "factor")), .Names = c("vnum1", "vnum2", "vch1" ), row.names = c(NA, -5L), class = c("data.table", "data.frame" )) > mydf[,round(.SD,1),] Error in Math.data.frame(list(vnum1 = c(0.590165705411504, -1.39939534199836, : non-numeric variable in data frame: vch1 > cbind(mydf[,3,with=F], mydf[,1:2,with=F][,round(.SD,1),]) vch1 vnum1 vnum2 1: B 0.6 0.7 2: E -1.4 0.5 3: A 0.7 0.9 4: C -0.3 0.8 5: C -0.8 0.6

¿Hay un método mejor (código más corto)? Gracias por tu ayuda.


Dado que dplyr::mutate_each ha quedado en desuso, use mutate_if con el beneficio adicional de redondear una columna solo si es numérico

mydf %>% mutate_if(is.numeric, round, 1)


Más corto por mucho:

mydf[, lapply(.SD, round, digits = 1), by = vch1, .SDcols = "vnum1"]

Método interesante. Pero, ¿qué pasa si tengo muchas columnas, por ejemplo: (vnum1, vnum2, vch1, vch2, vbin1, vbin2, vbin3) y quiero redondear solo vnum1 y vnum2? Además, alguna explicación sobre cómo está funcionando será muy útil.

Es agrupar por columnas redondeadas utilizando "by =" de data.table.

Este es el ejemplo basado en este método para resolver su tarea de segundo nivel.

Conjunto de datos incorporado:

mydf[, vch1, round(mydf[, 1:2], 1)] # vnum1 vnum2 vch1 #1: 0.6 0.7 B #2: -1.4 0.5 E #3: 0.7 0.9 A #4: -0.3 0.8 C #5: -0.8 0.6 C

Solución corta:

>dt <- data.table(names = rownames(datasets::ability.cov$cov), datasets::ability.cov$cov) >dt # names general picture blocks maze reading vocab #1: general 24.641 5.991 33.520 6.023 20.755 29.701 #2: picture 5.991 6.700 18.137 1.782 4.936 7.204 #3: blocks 33.520 18.137 149.831 19.424 31.430 50.753 #4: maze 6.023 1.782 19.424 12.711 4.757 9.075 #5: reading 20.755 4.936 31.430 4.757 52.604 66.762 #6: vocab 29.701 7.204 50.753 9.075 66.762 135.292

Orden inicial de las columnas:

> dt_round <- dt[, .SD, by = round(dt[, blocks:maze], 1)] > dt_round # blocks maze names general picture reading vocab #1: 33.5 6.0 general 24.641 5.991 20.755 29.701 #2: 18.1 1.8 picture 5.991 6.700 4.936 7.204 #3: 149.8 19.4 blocks 33.520 18.137 31.430 50.753 #4: 19.4 12.7 maze 6.023 1.782 4.757 9.075 #5: 31.4 4.8 reading 20.755 4.936 52.604 66.762 #6: 50.8 9.1 vocab 29.701 7.204 66.762 135.292


Si no te importa sobreescribir tu mydf original:

cols <- names(mydf)[1:2] mydf[,(cols) := round(.SD,1), .SDcols=cols] mydf # vnum1 vnum2 vch1 #1: 0.6 0.7 B #2: -1.4 0.5 E #3: 0.7 0.9 A #4: -0.3 0.8 C #5: -0.8 0.6 C


Utilizando dplyr

Si quieres redondear varias columnas a la vez:

mydf %>% mutate(vnum1 = round(vnum1, 1), vnum2 = round(vnum2, 1))

O, si desea cambiar todas las columnas excepto "vch1":

mydf %>% mutate_each(funs(round(.,1)), vnum1, vnum2)

O, si desea cambiar todas las columnas que comienzan con "vnum":

mydf %>% mutate_each(funs(round(.,1)), -vch1)

O, si quieres cambiar solo las columnas numéricas:

cols <- names(mydf)[1:2] mydf %>% mutate_each_(funs(round(.,1)), cols)

Usted obtiene:

mydf %>% mutate_each(funs(round(.,1)), starts_with("vnum"))


requiere (data.table)

Solución corta y clara:

vnum1 vnum2 vch1 1 0.6 0.7 B 2 -1.4 0.5 E 3 0.7 0.9 A 4 -0.3 0.8 C 5 -0.8 0.6 C

Lo mismo, pero con detalles descriptivos:

mydf[, lapply(.SD, round, 1), vch1] # vch1 vnum1 vnum2 #1: B 0.6 0.7 #2: E -1.4 0.5 #3: A 0.7 0.9 #4: C -0.3 0.8 #5: C -0.8 0.6

Si tengo muchas columnas, diga: (vnum1, vnum2, vch1, vch2, vbin1, vbin2, vbin3) y quiero redondear solo vnum1 y vnum2?

En este caso, puede usar := operator y .SDcols = argumento para especificar columnas para redondear:

mydf[, lapply(.SD, round, digits = 1), by = vch1]

En caso de que necesite redondear ciertas columnas y excluir otras de la salida, puede usar solo el argumento .SDcols = para hacer ambas cosas a la vez:

mydf[, 1:2 := lapply(.SD, round, digits = 1), by = vch1]

.SDcols = puede suministrarse con el nombre de la columna o su número,
como una sola columna por nombre .SDcols = "vnum1" o por número .SDcols = 1
como varias columnas por nombres .SDcols = c("vnum2", "vnum1") o por números .SDcols = c(2, 1)
como un rango de columnas por nombres .SDcols = vnum1:vnum2 o por números .SDcols = 1:2