vacio - tablas en r
Suma de filas sobre columnas con un patrĂ³n determinado en su nombre (3)
La solución de dplyr
sería usar mutate_
junto con paste(listCol, collapse = "+")
. Pero supongo que la solución Reduce
es más rápida.
DT <- mutate_(DT, sum = paste(listCol, collapse = "+"))
Tengo una tabla de datos como esta
dput(DT)
structure(list(ref = c(3L, 3L, 3L, 3L), nb = 12:15, i1 = c(3.1e-05,
0.044495, 0.82244, 0.322291), i2 = c(0.000183, 0.155732, 0.873416,
0.648545), i3 = c(0.000824, 0.533939, 0.838542, 0.990648), i4 = c(0.044495,
0.82244, 0.322291, 0.393595)), .Names = c("ref", "nb", "i1",
"i2", "i3", "i4"), row.names = c(NA, -4L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x0000000000320788>)
DT
# ref nb i1 i2 i3 i4
# 1: 3 12 0.000031 0.000183 0.000824 0.044495
# 2: 3 13 0.044495 0.155732 0.533939 0.822440
# 3: 3 14 0.822440 0.873416 0.838542 0.322291
# 4: 3 15 0.322291 0.648545 0.990648 0.393595
Ahora quiero calcular sumas de filas, pero solo incluir columnas que comiencen con una "i" ("i1", "i2", etc.)
He usado grep
para crear un vector de los nombres de columna que se van a sumar:
listCol <- colnames(DT)[grep("i", colnames(DT))]
listCol
# [1] "i1" "i2" "i3" "i4"
Entonces he tratado de pasar por encima de las columnas:
DT$sum <- rep.int(0, nrow(DT))
for (i in listCol){
DT$sum = DT$sum + DT[ , get(i)]
}
... lo que da la salida deseada:
DT
# ref nb i1 i2 i3 i4 sum
# 1: 3 12 0.000031 0.000183 0.000824 0.044495 0.045533
# 2: 3 13 0.044495 0.155732 0.533939 0.822440 1.556606
# 3: 3 14 0.822440 0.873416 0.838542 0.322291 2.856689
# 4: 3 15 0.322291 0.648545 0.990648 0.393595 2.355079
¿Cómo puedo mejorar mi código?
Sub pregunta:
Esta sub-pregunta incluye parcialmente la respuesta a la anterior:
Cómo evitar este tipo de notación extraña:
myrowMeans = function (x){
rowMeans(x, na.rm = TRUE)
}
DT[ , var := myrowMeans(.SD-myrowMeans(.SD)^2), .SDcols = grep("i", colnames(DT))]
También puedes probar con Reduce
DT[, Sum := Reduce(`+`, .SD), .SDcols=listCol][]
# ref nb i1 i2 i3 i4 Sum
#1: 3 12 0.000031 0.000183 0.000824 0.044495 0.045533
#2: 3 13 0.044495 0.155732 0.533939 0.822440 1.556606
#3: 3 14 0.822440 0.873416 0.838542 0.322291 2.856689
#4: 3 15 0.322291 0.648545 0.990648 0.393595 2.355079
NOTA: Si hay valores "NA", debe reemplazarse con ''0'' antes de Reduce
es decir
DT[, Sum := Reduce(`+`, lapply(.SD, function(x) replace(x,
which(is.na(x)), 0))), .SDcols=listCol][]
** Otra solución: ** usando rowSums
DT[, Sum := rowSums(.SD, na.rm = TRUE), .SDcols = grep("i", names(DT))]
Use .SDcols
para especificar las columnas, luego tome rowSums
. Use :=
para asignar nuevas columnas:
DT[ ,sum := rowSums(.SD), .SDcols = grep("i", names(DT))]