Sumar filas en data.frame o matriz

Resuelto user483502 asked hace 54 años • 0 respuestas

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])
user483502 avatar Jan 01 '70 08:01 user483502
Aceptado

puedes usarrowSums

rowSums(data)debería darte lo que quieres.

Greg avatar Oct 21 '2010 21:10 Greg

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.

Greg Snow avatar Oct 21 '2010 21:10 Greg Snow

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 cbindfunción:

cbind(data, total = rowSums(data))

Este método agrega una totalcolumna 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

seeiespi avatar Jul 13 '2018 00:07 seeiespi

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:12puedes 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
rubengavidia0x avatar Mar 30 '2022 00:03 rubengavidia0x