2016-05-30

Añadir una columna con el min y max por grupo en R

Title

Problema

Deseamos añadir dos columnas con el mínimo y máximo de la columna old.var para cada grupo de la columna id: 1, 2 y 3.

  id old.var
1  1       1
2  1       2
3  1       3
4  2       5
5  2       7
6  2       9
7  2      11
8  3       3
9  3       4

  • Datos originales
  • df <- structure(list(id = c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L), old.var = c(1L, 
    2L, 3L, 5L, 7L, 9L, 11L, 3L, 4L)), .Names = c("id", "old.var"
    ), class = "data.frame", row.names = c(NA, -9L))
    

    Solución

  • Paquete base
  • df$min.var <- ave(df$old.var, df$id, FUN = min)
    df$max.var <- ave(df$old.var, df$id, FUN = max)
    
  • Paquete dplyr
  • library(dplyr)
    df %>% 
      group_by(id) %>%
      mutate(min.var = min(old.var), max.var = max(old.var))
    
      id old.var min.var max.var
    1  1       1       1       3
    2  1       2       1       3
    3  1       3       1       3
    4  2       5       5      11
    5  2       7       5      11
    6  2       9       5      11
    7  2      11       5      11
    8  3       3       3       4
    9  3       4       3       4
    

    Referencias

    2016-05-28

    Filtrar filas de un data frame en función de múltiples condiciones en R

    Title

    Problema

    Queremos filtrar el siguiente data frame, conservando aquellas filas que contengan el valor 123 o 321.

      Index odx1 odx2 odx3 odx4 odx5
    1     1  123    0    0    0    0
    2     2    0  321    0    0    0
    3     3    0    0    0  123    0
    4     4    0  321    0    0    0
    5     5    0    0    0    0    0
    

  • Datos originales
  • df <- structure(list(Index = 1:5, odx1 = c(123L, 0L, 0L, 0L, 0L), odx2 = c(0L, 
    321L, 0L, 321L, 0L), odx3 = c(0L, 0L, 0L, 0L, 0L), odx4 = c(0L, 
    0L, 123L, 0L, 0L), odx5 = c(0L, 0L, 0L, 0L, 0L)), .Names = c("Index", 
    "odx1", "odx2", "odx3", "odx4", "odx5"), class = "data.frame", row.names = c(NA, 
    -5L))
    

    Solución

  • Paquete base
  • df[apply(df, 1, function(x) {any(x == 123| x == 321)}),]
    
  • Paquete dplyr
  • library(dplyr)
    filter(df, rowSums(mutate_each(df, funs(. %in% c(123, 321)))) >= 1L)
    
    Con mutate creamos una matriz de valores lógicos que evaluamos con rowSums.

    mutate_each(df, funs(. %in% c(123, 321)))
      Index odx1 odx2 odx3 odx4 odx5
    1     1  123    0    0    0    0
    2     2    0  321    0    0    0
    3     3    0    0    0  123    0
    4     4    0  321    0    0    0
    

    Referencias

    2016-05-18

    Convertir de formato largo a ancho con la función unstack en R

    Title

    Problema

    Deseamos transformar un data frame de formato largo a ancho. Partimos del siguiente data frame:

            name numbers      value
    1  firstName       1 -0.3016990
    2  firstName       2  0.4782982
    3  firstName       3 -0.3274221
    4  firstName       4  0.8950889
    5 secondName       1 -1.3476795
    6 secondName       2 -0.4671124
    7 secondName       3 -1.0883609
    8 secondName       4  1.8702156
    

    Y queremos llegar a este otra. Con name como nombres de filas, cuatro columnas basadas en numbers y como valores, values.

                      X1         X2         X3        X4
    firstName  -0.301699  0.4782982 -0.3274221 0.8950889
    secondName -1.347680 -0.4671124 -1.0883609 1.8702156
    

  • Datos originales
  • dat1 <- structure(list(name = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
    2L), .Label = c("firstName", "secondName"), class = "factor"), 
        numbers = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), value = c(-0.301698990300544, 
        0.47829821507312, -0.327422119821659, 0.895088877410118, 
        -1.3476795169412, -0.467112422933039, -1.08836089961649, 
        1.87021564288651)), .Names = c("name", "numbers", "value"
    ), row.names = c(NA, -8L), class = "data.frame")
    

    Solución

  • Paquete base
  • Empleamos la función unstack para transformar de formato largo a ancho. En el primer argumento, indicamos el data frame, en el argumento form una fórmula, a la izquierda de ~ el vector que deseamos desapilar —unstack— (value) y a la derecha los grupos que queremos crear (numbers). Finalmente, renombramos los nombres de las filas.

    df <- unstack(dat1, form = value ~ numbers)
    rownames(df) <- unique(dat1$name)
    df
    
                      X1         X2         X3        X4
    firstName  -0.301699  0.4782982 -0.3274221 0.8950889
    secondName -1.347680 -0.4671124 -1.0883609 1.8702156
    

    Entradas relacionadas

    Referencias

    2016-05-11

    Muestra aleatoria basada en una columna en R

    Title

    Problema

    Queremos extraer del siguiente data frame una muestra aleatoria basada en la columna id, de manera que seleccionemos aleatoriamente dos ids y extraigamos todas las filas asociadas a los mismos. Por ejemplo, si seleccionamos aleatoriamente los ids 1 y 2, el resultado debería incluir las tres primeras filas.

      id     date      date2
    1  1 23-01-08 2008-01-23
    2  1 01-11-07 2007-11-01
    3  2 30-11-07 2007-11-30
    4  3 17-12-07 2007-12-17
    5  3 12-12-08 2008-12-12
    
    id<-c(1,1,2,3,3)
    date<-c("23-01-08","01-11-07","30-11-07","17-12-07","12-12-08")
    df<-data.frame(id,date)
    df$date2<-as.Date(as.character(df$date), format = "%d-%m-%y")
    

    Soluciones

  • Paquete base
  • a <- sample(unique(df$id), 2)
    subset(df, id %in% a)
    
  • sqldf
  • library(sqldf)
    a <- sqldf("SELECT DISTINCT id FROM df  ORDER BY RANDOM(*) LIMIT 2")
    sqldf("SELECT * FROM df WHERE id IN a")
    
      id     date      date2
    1  1 23-01-08 2008-01-23
    2  1 01-11-07 2007-11-01
    3  2 30-11-07 2007-11-30
    

    Entradas relacionadas

    Referencias

    2016-05-08

    Buscar el mínimo o máximo de una columna basado en una condición en Excel

    Title

    Problema

    Para cada pedido de la siguiente tabla queremos extraer el precio mínimo y el máximo.

    Solución

    Utilizamos las siguientes fórmulas matriciales en las celdas J2 y M2 de nuestro ejemplo, sin las llaves {}, y arrastramos el controlador de relleno hacia abajo. En la barra de fórmulas antes de salir, presionamos Ctrl+Mayús+Entrar para indicar que se trata de una fórmula matricial y Excel las añadirá automáticamente.

  • Mínimo
  • {=MIN(SI(H2=$A$2:$A$18;$C$2:$C$18))}
    
  • Máximo
  • {=MAX(SI(H2=$A$2:$A$18;$C$2:$C$18))}
    

    Entradas relacionadas

    Referencias

    Directrices y ejemplos de fórmulas de matriz

    2016-05-04

    Eliminar duplicados de un data frame basándonos en dos columnas en R

    Title

    Problema

    Queremos eliminar las filas duplicadas, considerando éstas como aquellas que tienen el mismo valor en las columnas col1 y col2 ignorando su orden. En el siguiente ejemplo solamente conservaríamos una fila.

      Col1 Col2 database
    1    A    B   IntAct
    2    A    B     Bind
    3    B    A  BioGrid
    
    df <- structure(list(Col1 = c("A", "A", "B"), Col2 = c("B", "B", "A"
    ), database = c("IntAct", "Bind", "BioGrid")), .Names = c("Col1", 
    "Col2", "database"), class = "data.frame", row.names = c(NA, 
    -3L))
    

    Solución

    Emplearemos el paquete sqldf.

  • Primera fila
  • En el caso de querer conservar la primera fila. Creamos una columna id para identificar la primera ocurrencia.

    library(sqldf)
    df$id <- seq.int(nrow(df))
    sqldf("select col1, col2, database, min(id) id
          from (select col1, col2, database, id from df where col1 <= col2
          union all
          select col2 col1, col1 col2, database, id from df where col1 > col2) 
          group by col1, col2")
    
      col1 col2 database id
    1    A    B   IntAct  1
    

  • Última fila
  • En el caso de querer conservar la última fila. En este caso el código es más conciso pues no necesitamos crear una columna para identificar la primera ocurrencia.

    sqldf("select col1, col2, database 
          from (select col1, col2, database from df where col1 <= col2 
          union all 
          select col2 col1, col1 col2, database from df where col1 > col2) 
          group by col1, col2")
    
     col1 col2 database
    1    A    B  BioGrid
    

    Entradas relacionadas

    Referencias

    Nube de datos