2012-01-27 14 views
6

Tengo dos tablas, y estoy tratando de buscar valores de uno para agregar a valores en el otro. Actualmente estoy usando dos bucles pero funcionan lentamente. Soy nuevo en R y sé que debería evitar el bucle para acelerar las cosas, pero no puedo entender cómo.Búsqueda sin bucle

Tabla1 (varios miles de filas, 37 columnas):

type cat1 cat2 cat3 ... cat36 
    1 2 3 2   7 
    3 6 2 1   9 
    2 4 6 7   4 
    3 5 7 8   2 
    5 2 2 9   1 
    4 3 1 2   3 
    1 8 1 4   4 
...

Tabla2 (36 filas, 5 columnas):

  type1 type2 type3 type4 type5 
cat1  2  3  4  3  8 
cat2  8  5  5  2  6 
cat3  7  5  1  3  5 
... 
cat36  4  7  2  8  9

Quiero modificar cada valor en la Tabla 1 mediante la adición del valor apropiado (coincidencia entre los 5 tipos y 36 categorías) de la Tabla2. Aquí están los resultados deseados:

type cat1 cat2 cat3 ... cat36 
    1 4 11 9  11 
    3 10 7 2  11 
    2 7 11 12  11 
    3 9 12 9   4 
    5 10 8 14  10 
    4 6 3 5  11 
    1 10 9 11   8 
...

Aquí está mi actual (lento) código:

for (i in 1:36) { 
    for (j in 1:nrow(Table1)) { 
     Table1[j,i+1] = Table1[j,i+1] + Table2[i,Table1[j,1]] 
    } 
} 
+1

Aunque he utilizado dos bucles para mayor claridad, voy a señalar que podría tener apenas tenía un bucle a través de las filas de la Tabla 1, la adición de la columna apropiada de la Tabla 2 para cada fila Tabla 1 . –

Respuesta

4

La columna de tipo en la Tabla 1 indica qué columnaen la Tabla2 a añadir a los filas en la Tabla 1 . Así que utilice la columna "tipo" como un índice para las filas Table2, y luego transponer la matriz resultante para que pueda agregar filas a las filas:.

Table3 <- cbind(Table1[ , "type"], 
       t(Table2[ , Table1[ , "type"] ]) + Table1[ , -1]) 

(Estoy asumiendo que la Tabla 1 y Tabla 2 son matrices Si se son marcos de datos que puede usar Table1$type en lugar de Table1[,"type"]).

+0

Gracias. Lo hice funcionar después de corregir un error tipográfico. En lugar de 'Table2 [Table1 [," type "],]' debe ser 'Table2 [, Table1 [," type "]]' –

+0

Vaya, tiene usted razón. ¡Me confundí al transponer entre filas y columnas! – Tyler

1

Transformaría ambas tablas para que sean "largas" en lugar de dos formatos "anchos" diferentes. Después de hacer que ambas tablas sean largas, podría realizar una fusión (R data.frame analog a SQL join) en las dos tablas y luego sumar trivialmente los valores.

Aquí hay un ejemplo similar:

## creating some synthetic data 
df1 <- data.frame(type=sample(1:4, 100, replace=TRUE), cat1=sample(1:4, 100, replace=TRUE), cat2=sample(1:4, 100, replace=TRUE),cat3=sample(1:4, 100, replace=TRUE),cat4=sample(1:4, 100, replace=TRUE)) 
df2 <- data.frame(cat=1:4, type1=sample(1:4,4), type2=sample(1:4,4), type3=sample(1:4,4), type4=sample(1:4,4)) 

require(reshape) 

## rearrange df1 
m1 <- melt(df1, id.vars="type") 
m1$cat <- substr(m1$variable, 4,4) 
m1$variable <- NULL 

## rearrange df2 
m2 <- melt(df2, id.vars="cat") 
m2$type <- substr(m2$variable, 5, 5) 
m2$value2 <- m2$value 
m2$variable <- NULL 
m2$value <- NULL 

## now that they are laid out the same, they can be merged 
df3 <- merge(m1, m2) 
df3$newSum <- df3$value + df3$value2 
Cuestiones relacionadas