Sumar filas en data.frame o matriz
Tengo un marco de datos muy grande con filas como observaciones y columnas como marcadores genéticos. Me gustaría crear una nueva columna que contenga la suma de un número seleccionado de columnas para cada observación usando R.
Si tengo 200 columnas y 100 filas, entonces me gustaría crear una nueva columna que tenga 100 filas con la suma de, digamos, las columnas 43 a 167. Las columnas tienen 1 o 0. Con la nueva columna que contiene la suma de En cada fila, podré ordenar los individuos que tienen más marcadores genéticos.
Siento que es algo parecido a:
data$new=sum(data$[,43:167])
puedes usarrowSums
rowSums(data)
debería darte lo que quieres.
La función rowSums (como menciona Greg) hará lo que quieras, pero estás mezclando técnicas de subconjunto en tu respuesta, no uses "$" cuando uses "[]", tu código debería verse más parecido a:
data$new <- rowSums( data[,43:167] )
Si desea utilizar una función distinta a la suma, consulte ?apply para aplicar funciones generales en filas o columnas.
Vine aquí con la esperanza de encontrar una manera de obtener la suma de todas las columnas de una tabla de datos y tuve problemas al implementar las soluciones anteriores. Una forma de agregar una columna con la suma de todas las columnas utiliza la cbind
función:
cbind(data, total = rowSums(data))
Este método agrega una total
columna a los datos y evita el problema de alineación que se produce al intentar sumar TODAS las columnas utilizando las soluciones anteriores (consulte la publicación a continuación para obtener una discusión sobre este problema).
Agregar una nueva columna al error de matriz
Sólo para completar. Enumeraré otros métodos que no se mencionan aquí, estas son diferentes formas de hacer lo mismo usando la sintaxis dplyr con una matriz:
mat = matrix(1:12, ncol = 3)
library(dplyr)
mat %>% as_tibble() %>%
mutate(sum = rowSums(across(where(is.numeric))))
# A tibble: 4 x 4
V1 V2 V3 sum
<int> <int> <int> <dbl>
1 1 5 9 15
2 2 6 10 18
3 3 7 11 21
4 4 8 12 24
o c_across:
mat %>% as_tibble() %>%
rowwise() %>%
mutate(sumrange = sum(c_across(), na.rm = T))
o seleccionando una columna específica por nombre de columna:
mat %>% as_tibble() %>%
mutate( 'B1' = V1, B2 = V2) %>%
rowwise() %>%
mutate(sum_startswithB =
sum(c_across(starts_with("B")), na.rm = T))
V1 V2 V3 B1 B2 sum_startswithx
<int> <int> <int> <int> <int> <int>
1 1 5 9 1 5 6
2 2 6 10 2 6 8
3 3 7 11 3 7 10
4 4 8 12 4 8 12
por índice de columna, en este caso de la primera columna a la cuarta columna:
mat %>% as_tibble() %>%
mutate( 'B1' = V1, B2 = V2) %>%
rowwise() %>%
mutate(SumByIndex = sum(c_across(c(1:4)), na.rm = T))
V1 V2 V3 B1 B2 SumByIndex
<int> <int> <int> <int> <int> <int>
1 1 5 9 1 5 16
2 2 6 10 2 6 20
3 3 7 11 3 7 24
4 4 8 12 4 8 28
Usando expresiones regulares:
mat %>% as_tibble() %>%
mutate( 'B1' = V1, B2 = V2) %>%
mutate(sum_V = rowSums(.[grep("V[2-3]", names(.))], na.rm = TRUE),
sum_B = rowSums(.[grep("B", names(.))], na.rm = TRUE))
V1 V2 V3 B1 B2 sum_V sum_B
<int> <int> <int> <int> <int> <dbl> <dbl>
1 1 5 9 1 5 14 6
2 2 6 10 2 6 16 8
3 3 7 11 3 7 18 10
4 4 8 12 4 8 20 12
Usar la función Aplicar es más útil porque puede elegir la suma, la media, el máximo, el mínimo, la varianza y la desviación estándar en todas las columnas.
mat %>% as_tibble() %>%
mutate( 'B1' = V1, B2 = V2) %>%
mutate(sum = select(., V1:B1) %>% apply(1, sum, na.rm=TRUE)) %>%
mutate(mean = select(., V1:B1) %>% apply(1, mean, na.rm=TRUE)) %>%
mutate(max = select(., V1:B1) %>% apply(1, max, na.rm=TRUE)) %>%
mutate(min = select(., V1:B1) %>% apply(1, min, na.rm=TRUE)) %>%
mutate(var = select(., V1:B1) %>% apply(1, var, na.rm=TRUE)) %>%
mutate(sd = select(., V1:B1) %>% apply(1, sd, na.rm=TRUE))
V1 V2 V3 B1 B2 sum mean max min var sd
<int> <int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> <dbl>
1 1 5 9 1 5 16 4 9 1 14.7 3.83
2 2 6 10 2 6 20 5 10 2 14.7 3.83
3 3 7 11 3 7 24 6 11 3 14.7 3.83
4 4 8 12 4 8 28 7 12 4 14.7 3.83
Nota: la misma salida de var y sd no es un error porque los datos se generan linealmente 1:12
puedes verificar calculando los valores de las primeras columnas:
> sd(c(1,5,9,1))
[1] 3.829708
> sd(c(2,6,10,2))
[1] 3.829708