R Versión 2.11.1 de 32 bits en Windows 7

Tengo dos conjuntos de datos: data_A y data_B:

data_A

USER_A USER_B ACTION
1      11     0.3
1      13     0.25
1      16     0.63
1      17     0.26
2      11     0.14
2      14     0.28

data_B

USER_A USER_B ACTION
1      13     0.17
1      14     0.27
2      11     0.25

Ahora quiero agregar la ACCIÓN de data_B a la data_A si su USER_A y USER_B’son iguales. Como el ejemplo de arriba, el resultado sería:

data_A

USER_A USER_B ACTION
1      11     0.3
1      13     0.25+0.17
1      16     0.63
1      17     0.26
2      11     0.14+0.25
2      14     0.28

¿Cómo podría conseguirlo?

  • Normalmente, yo uso la awk o perl para esto. Sería una solución a estar bien?
  • Posibles duplicados de Cómo combinar y suma dos tramas de datos
  • Mientras que el anterior relacionado pregunta es más reciente, que tiene más de un número de más agradable, más los enfoques actuales.
InformationsquelleAutor PepsiCo | 2011-04-24

3 Comentarios

  1. 17

    Puede utilizar ddply en el paquete plyr y combinarlo con merge:

    library(plyr)
    ddply(merge(data_A, data_B, all.x=TRUE), 
      .(USER_A, USER_B), summarise, ACTION=sum(ACTION))

    Aviso que merge se llama con el parámetro all.x=TRUE – devuelve todos los valores de los primeros datos.marco pasó a merge, es decir, data_A:

      USER_A USER_B ACTION
    1      1     11   0.30
    2      1     13   0.25
    3      1     16   0.63
    4      1     17   0.26
    5      2     11   0.14
    6      2     14   0.28
    • Que la salida no es lo que el OP ha – aviso usted tiene una fila adicional de la OP quería. Necesitamos data_A pero con una actualización de dos de los ACTION entradas. El equivalente de la base R de su respuesta sería: aggregate(ACTION ~ USER_B + USER_A, data = rbind(data_A, data_B), FUN = sum)[, c(2,1,3)] pero me descontado esto, porque no era una actualización de data_A.
    • Gracias por esta manchado. Ahora he modificado el código para usar en combinación, en lugar de rbind.
    • Muere rápido en los dos conjuntos de 3M cada una de las filas después de consumir de 2 gb de ram.
    • Si quieres un procesamiento más rápido y con menor consumo de memoria, tratar los datos.tabla paquete
    • me estoy perdiendo algo? OP pidió a la acción valor de la columna que se va a sumar, pero esta respuesta no?
    • Si puedo reemplazar el «merge» con rbind puedo conseguir algo que funcione.

  2. 15

    Este tipo de cosas es bastante fácil de hacer con una base de datos de la operación. Aquí uso el paquete de sqldf a hacer una a la izquierda (exterior) de combinación y, a continuación, resumen el objeto resultante:

    require(sqldf)
    tmp <- sqldf("select * from data_A left join data_B using (USER_A, USER_B)")

    Esto se traduce en:

    > tmp
      USER_A USER_B ACTION ACTION
    1      1     11   0.30     NA
    2      1     13   0.25   0.17
    3      1     16   0.63     NA
    4      1     17   0.26     NA
    5      2     11   0.14   0.25
    6      2     14   0.28     NA

    Ahora solo falta que la suma de los dos ACTION columnas:

    data_C <- transform(data_A, ACTION = rowSums(tmp[, 3:4], na.rm = TRUE))

    Que da el resultado deseado:

    > data_C
      USER_A USER_B ACTION
    1      1     11   0.30
    2      1     13   0.42
    3      1     16   0.63
    4      1     17   0.26
    5      2     11   0.39
    6      2     14   0.28

    Esto se puede hacer utilizando el estándar de la función de R merge:

    > merge(data_A, data_B, by = c("USER_A","USER_B"), all.x = TRUE)
      USER_A USER_B ACTION.x ACTION.y
    1      1     11     0.30       NA
    2      1     13     0.25     0.17
    3      1     16     0.63       NA
    4      1     17     0.26       NA
    5      2     11     0.14     0.25
    6      2     14     0.28       NA

    Por lo que podemos sustituir la sqldf() la llamada anterior con:

    tmp <- merge(data_A, data_B, by = c("USER_A","USER_B"), all.x = TRUE)

    mientras que la segunda línea mediante transform() sigue siendo el mismo.

    • Usted puede simplemente añadir estos en la consulta SQL, y entonces no hay ninguna necesidad de que el transform. por ejemplo SELECT A.USER_A, B.USER_B, A.ACTION + B.ACTION AS ACTION FROM data_A A INNER JOIN data_B B ON A.USER_A = B.USER_B
    • Esta respuesta obras, mientras yo trataba mucho con aceptó responder sin lograr…+1
  3. 1

    Escribí el paquete safejoin que resuelve esta muy succintly :

    # devtools::install_github("moodymudskipper/safejoin")
    library(safejoin)
    safe_left_join(data_A,data_B, by = c("USER_A", "USER_B"), 
                   conflict = ~ .x+ ifelse(is.na(.y),0,.y))
    #   USER_A USER_B ACTION
    # 1      1     11   0.30
    # 2      1     13   0.42
    # 3      1     16   0.63
    # 4      1     17   0.26
    # 5      2     11   0.39
    # 6      2     14   0.28

    En caso de conflicto, la función de la fed a la conflict argumento será utilizado
    en los pares de conflicto en las columnas

Dejar respuesta

Please enter your comment!
Please enter your name here