2011-01-15 18 views
7

Tengo dos tramas de datos, al igual que éstos:acelerar trama de datos a juego

data = data.frame(data=cbind(1:12,rep(c(1,2),6),rep(c(1,2,3),4))) 
colnames(data)=c('v','h','c') 

lookup = data.frame(data=cbind(c(rep(1,3),rep(2,3)),rep(c(1,2,3),2),21:26)) 
colnames(lookup)=c('h','c','t') 

quiero restar de búsqueda $ t $ a partir de datos v donde el h y c columnas partido.

pensé que algo como esto funcionaría

data$v-lookup$t[lookup$h==data$h&lookup$c==data$c] 

pero no mágicamente saber que quiero repetir implícita sobre las filas de datos

acabé haciendo esto

myt = c() 
for(i in 1:12) { 
myt[i] = lookup$t[lookup$h==data$h[i]&lookup$c==data$c[i]] 
} 

que funciona bien, pero espero que alguien pueda sugerir una forma más sensata que no implique un ciclo.

Respuesta

8

suena como que podría fusionarse y luego hacer los cálculos:

dataLookedUp <- merge(data, lookup) 
dataLookedUp$newValue <- with(dataLookedUp, v - t) 

para sus datos reales, es la fusión y calc más rápido?

Si los datos y/o la búsqueda son realmente grandes, puede usar data.table para crear un índice antes de la fusión con el fin de acelerarlo.

4

Con sus columnas enteras, no creo que haya nada que pueda hacer para mejorar la oferta de JD, pero si tuviera cadenas en las columnas en las que se fusiona, podría crear factores con as.factor, lo que podría acelerar el merge, dependiendo del tamaño del conjunto de datos y el número de fusiones/tipo que anticipan:

data <- data.frame(v = 1:12, h = rep(c("one", "two"), 6), c = rep(c("one", "two", "three"), 4)) 
lookup <- data.frame(h = c(rep("one", 3), rep("two", 3)), c = rep(c("one", "two", "three"), 2), t = 21:26) 
data <- transform(data, h = as.factor(h), c = as.factor(c)) 
lookup <- transform(lookup, h = as.factor(h), c = as.factor(c)) 
temp <- merge(data, lookup) 
temp <- transform(temp, v.minus.t = v - t) 
+0

en realidad, son todas las cadenas, porque soy terrible en la creación de tramas de datos. ¡Gracias! – ansate

+0

@ansate - FWIW, puede jugar con su opción 'stringsAsFactors' y las opciones' read.table' para que las cadenas se lean como factores por defecto. El valor predeterminado debe ser leer cadenas como factores. –

6

Una alternativa que es 1.) más familiar para aquellos que están acostumbrados a las consultas SQL y 2.) a menudo más rápido que el estándar de combinación es usar el paquete sqldf. (Tenga en cuenta que en Mac OS X, es probable que desee instalar Tcl/Tk, de lo que depende sqldf). Como una ventaja adicional, sqldf convierte las cadenas en factores automágicamente por defecto.

install.packages("sqldf") 
library(sqldf) 
data <- data.frame(v = 1:12, h = rep(c("one", "two"), 6), c = rep(c("one", "two", "three"), 4)) 
lookup <- data.frame(h = c(rep("one", 3), rep("two", 3)), c = rep(c("one", "two", "three"), 2), t = 21:26) 
soln <- sqldf("select * from data inner join lookup using (h, c)") 
soln <- transform(soln, v.minus.t = v - t) 
+0

Tenga en cuenta que las dos últimas líneas podrían combinarse así: 'sqldf (" select *, v - t como 'v.minus.t' de la búsqueda de unión de datos usando (h, c) ")' –

1

Esto es perfecto para el uso de data.tablesin que por

library(data.table) 
data <- as.data.table(data) 
lookup <- as.data.table(lookup) 
setkey(data, h, c) 
setkey(lookup, h,c) 

data[lookup, list(v,t, newValue = v-t)] 
Cuestiones relacionadas