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

    2016-04-29

    Análisis de tendencia en formato tabular en R

    Title

    Problema

    Tenemos unos datos que representamos gráficamente. Deseamos crear una tabla con los datos agrupados por site y parameter, y añadir una columna que nos indique la tendencia.

    # Ver apartado inferior Datos para crea el data frame df
    library(ggplot2)
    ggplot(df, aes(x = YEAR, y = value, col = parameter)) + geom_line(aes(group = parameter)) + facet_wrap(~siteID)
    

    Solución

    Una solución básica es transformar el data frame en un formato ancho (wide) y luego añadir una columna en la que establecemos las condiciones para: creciente, decreciente o sin tendencia. En nuestro ejemplo, establecemos que no hay tendencia si la variación es de +-2.

    
    df <- dcast(df, siteID + parameter ~ YEAR, value.var="value")
    df$trend <- ifelse(df$`2014`-df$`2011`>2, "creciente", 
                        ifelse(df$`2014`-df$`2011`< -2, "decreciente", "sin tendencia"))
    df
    
       siteID parameter 2011 2012 2013 2014         trend
    1   site1         A    1    2    3    4     creciente
    2   site1         B   10   20   30   40     creciente
    3   site1         C   12   14   16   18     creciente
    4   site1         D    5   10   15   20     creciente
    5   site2         A    3    6    9   12     creciente
    6   site2         B   17   16   13   18 sin tendencia
    7   site2         C   16   18   22   15 sin tendencia
    8   site2         D   17   16   10   11   decreciente
    9   site3         A    7    5    3    1   decreciente
    10  site3         B   15   17   20   19     creciente
    11  site3         C   15   17   16   18     creciente
    12  site3         D   13   16   19   11 sin tendencia
    13  site4         A    8    7    6    5   decreciente
    14  site4         B   50   40   30   20   decreciente
    15  site4         C   16   14   12   10   decreciente
    16  site4         D   20   15   10    5   decreciente
    

    Datos

    df <- structure(list(siteID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
    4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), .Label = c("site1", "site2", 
    "site3", "site4"), class = "factor"), YEAR = structure(c(1L, 
    2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
    2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
    2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
    2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("2011", 
    "2012", "2013", "2014"), class = "factor"), parameter = structure(c(1L, 
    1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 1L, 
    1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 1L, 
    1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 1L, 
    1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L), .Label = c("A", 
    "B", "C", "D"), class = "factor"), value = c(1, 2, 3, 4, 10, 
    20, 30, 40, 12, 14, 16, 18, 5, 10, 15, 20, 3, 6, 9, 12, 17, 16, 
    13, 18, 16, 18, 22, 15, 17, 16, 10, 11, 7, 5, 3, 1, 15, 17, 20, 
    19, 15, 17, 16, 18, 13, 16, 19, 11, 8, 7, 6, 5, 50, 40, 30, 20, 
    16, 14, 12, 10, 20, 15, 10, 5)), .Names = c("siteID", "YEAR", 
    "parameter", "value"), row.names = c(NA, -64L), class = "data.frame")
    
    

    Entradas relacionadas

    Referencias

    2016-04-24

    Comparar dos ficheros en Notepad++

    Title

    Problema

    Deseamos comparar dos ficheros con el editor Notepad++.

    Solución

  • Verticalmente
  • Hacemos clic con el botón secundario del ratón en la pestaña del fichero que deseamos que se muestre a la derecha y elegimos: Move to Other View.

  • Horizontalmente
  • Si queremos comparar los ficheros con una división horizontal, clic en la línea de división vertical con el botón derecho y presionamos Rotate to right.

  • Sincronizar barras de desplazamiento
  • Si queremos sincronizar las barras de desplazamiento para facilitar la comparación de los documentos, en el menú View elegimos Synchronize Vertical Scrolling o Synchronize Horizontal Scrolling.

    Entradas relacionadas

    2016-04-16

    Formato de número personalizado en miles y millones

    Title

    Problema

    Vamos dar dos formatos personalizados a números en Excel para obtener el siguiente resultado:

    Solución

  • Miles
  • [>=1000]#.##0."K";0
    
  • Millones
  • [>=1000000]#.##0.."M";[>=1000]#.##0."K";0
    

    Notas

    Podemos crear otras variantes, como por ejemplo:

  • Añadir un espacio entre el número y la letra
  • [>=1000000]#.##0.." M";[>=1000]#.##0." K";0
    

  • Añadir decimales
  • [>=1000000]#.##0,0.." M";[>=1000]#.##0,0." K";#.##0,00
    

    Entradas relacionadas

    2016-04-13

    Añadir caracteres a una columna de un data frame en R

    Title

    Problema

    Tenemos un data frame y queremos añadir a la primera columna los caracteres chr.

    df <- structure(list(V1 = c(1, 1, 1, 1, 2, 2), V2 = c(3423086, 3467184, 
    4115236, 5202437, 7132558, 7448688), V3 = c(3423685, 3467723, 
    4115672, 5203057, 7133089, 7449283)), .Names = c("V1", "V2", 
    "V3"), row.names = c(NA, -6L), class = "data.frame")
    
      V1      V2      V3
    1  1 3423086 3423685
    2  1 3467184 3467723
    3  1 4115236 4115672
    4  1 5202437 5203057
    5  2 7132558 7133089
    6  2 7448688 7449283
    

    Soluciones

    Disponemos de múltiples opciones.

    df <- paste("chr", df$V1, sep = "")
    df <- sub("^", "chr", df$V1 )
    df <- sprintf('chr%i', df$V1)
    df <- interaction( "chr", df$V1, sep = "")
    

    Resultado

       V1      V2      V3
    1 chr1 3423086 3423685
    2 chr1 3467184 3467723
    3 chr1 4115236 4115672
    4 chr1 5202437 5203057
    5 chr2 7132558 7133089
    6 chr2 7448688 7449283
    

    Referencias

    2016-04-03

    Cómo crear un histograma a partir de múltiples columnas en R

    Title

    Problema

    Tenemos un data frame con múltiples columnas —en nuestro ejemplo 49— y deseamos utilizar todas las columnas como una única variable. También calcularemos la media de todas las columnas.

    df <- read.table(textConnection("1.52 0.39 1.30 1.10 0.82 0.59 1.11 0.44 0.70 0.57 0.65 1.06 0.55 0.34 1.09 0.46 0.43 0.99 0.41 1.04 1.25 0.75 0.54 0.62 0.56 0.58 0.85 0.38 0.66 0.83 1.00 0.56 0.66 0.40 1.44 1.28 0.58 1.05 0.64 0.54 0.52 1.28 0.51 0.64 0.82 0.45 0.83 0.58 0.51"), header = FALSE)
    
        V1   V2  V3  V4   V5   V6   V7   V8  V9  V10  V11  V12  V13  V14  V15  V16  V17  V18  V19  V20  V21  V22  V23  V24  V25  V26  V27  V28
    1 1.52 0.39 1.3 1.1 0.82 0.59 1.11 0.44 0.7 0.57 0.65 1.06 0.55 0.34 1.09 0.46 0.43 0.99 0.41 1.04 1.25 0.75 0.54 0.62 0.56 0.58 0.85 0.38
       V29  V30 V31  V32  V33 V34  V35  V36  V37  V38  V39  V40  V41  V42  V43  V44  V45  V46  V47  V48  V49
    1 0.66 0.83   1 0.56 0.66 0.4 1.44 1.28 0.58 1.05 0.64 0.54 0.52 1.28 0.51 0.64 0.82 0.45 0.83 0.58 0.51
    

    Solución

  • Histograma
  • Simplemente transponemos el data frame antes de crear el histograma.

    hist(t(df))
    

  • Calculamos la media
  • Tenemos dos alternativas: mean o rowMeans.

    mean(t(df)) # or 
    rowMeans(df)
    

    [1] 0.752449 
    

    Entradas relacionadas

    Referencias

    Nube de datos