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))]