2011-01-15 3 views
7

У меня есть два dataframes, так же, как они:ускоряя кадр данных, соответствующий

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') 

Я хочу, чтобы вычесть подстановки $ т от данных $ V, где Н и С столбцами совпадают.

Я думал, что что-то подобное будет работать

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

но не волшебно знать, что я хочу, чтобы неявно перебирать строк данных

я в конечном итоге делает это

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

, который отлично работает, но я надеюсь, что кто-то может предложить более разумный способ, который не связан с циклом.

ответ

8

Похоже, вы могли бы объединить и затем сделать математику:

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

Для ваших реальных данных, является слияние и известково быстрее?

Если данные и/или поиск действительно большие, вы можете использовать data.table для создания индекса перед слиянием, чтобы ускорить его.

4

С вашими целыми столбцами я не думаю, что вы можете что-то сделать, чтобы улучшить предложение JD, но если бы у вас были строки в столбцах, на которых вы слились, вы могли бы создавать факторы с as.factor, что могло бы ускорить merge в зависимости от размера набора данных и сколько слияний/сортирую вы предполагаете:

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

в действительности, они являются строками, потому что я ужасен при создании кадров данных. благодаря! – ansate

+0

@ansate - FWIW, вы можете возиться со своей опцией 'stringsAsFactors' и параметрами' read.table', чтобы строки считались как факторы по умолчанию. Значение по умолчанию должно состоять в том, чтобы читать строки как факторы. –

6

альтернатива что 1.) более знакомы тех, кто привык к запросам SQL и 2) часто быстрее стандартное слияние заключается в использовании пакета sqldf. (Обратите внимание, что в Mac OS X вы, вероятно, захотите установить Tcl/Tk, от которого зависит sqldf.) В качестве дополнительного бонуса sqldf по умолчанию преобразует строки в факторы.

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

Обратите внимание, что последние две строки могут быть объединены следующим образом: 'sqldf (" select *, v - t as "v.minus.t 'из поиска соединения данных с использованием (h, c)") ' –

1

Это идеально подходит для data.table с помощью без по

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)] 
Смежные вопросы