2016-03-29 3 views
3

У меня есть кадр данных - вы можете воссоздать образец его на код ниже:извлечение данных/перекраивать из кадра данных в R

df = data.frame(M_id = c(rep(1000,8),rep(1001,8)), Day = c(rep(1,4),rep(2,4),rep(1,4),rep(2,4)), Half_hr = rep(1:4,4) ,Val = c(0.25,0.1,0.2,0.4,0.3,0.6,0.35,0.5,0.15,0.2,0.3,0.5,0.4,0.7,0.45,0.6)) 

Это выглядит следующим образом:

>df : 

M_id Day Half_hr  Val 
1000 1 1   0.25 
1000 1 2   0.1 
1000 1 3   0.2 
1000 1 4   0.4 
1000 2 1   0.3 
1000 2 2   0.6 
1000 2 3   0.35 
1000 2 4   0.5 
1001 1 1   0.15 
1001 1 2   0.2 
1001 1 3   0.3 
1001 1 4   0.5 
1001 2 1   0.4 
1001 2 2   0.7 
1001 2 3   0.45 
1001 2 4   0.6 

Здесь, в каждой строке, Val представляет значение для этого M_id за этот день в том, что Half_hr (Half_hr: 1,2 - это час 1 и 3,4 - час 2 и т. Д.). Мои фактические данные имеют так много Ids и Days и Val для 48 Half_hrs (в течение 24 часов).

Теперь я хочу объединить данные для каждого Half_hr в каждый час для каждого M_id за каждый день.

Мой вывод должен выглядеть следующим образом:

>df: 

M_id Day Hour_1 Hour_2 
1000 1 0.35 0.6 
1000 2 0.9  0.85 
1001 1 0.35 0.8 
1001 2 0.11 1.05 

Пример является M_id = 1000, день = 1, Hour_1 = Val (Half_hr-1 + Half_hr-2) = 0,25 + 0,1 = 0,35. Аналогично для Hour_2 = val (Half_hr-3 + Half_hr-4) = 0,2 + 0,4 = 0,6

Я сделал это, используя для циклов и sqldf, но это занимало много и много времени.

Я запрашиваю оптимизированный код, поскольку данные, которые я должен обрабатывать, имеют 1000 M_ids, каждый на 535 дней и 48 Half_hrs за каждый день (24 Hrs data).

ответ

3

Мы можем использовать data.table. Преобразование «data.frame» в «data.table» (setDT(df). Создайте переменную с помощью группировки gl после группировки по «M_id», «День», а затем использовать dcast конвертировать из «длинные» в формат «широкой»

library(data.table) 
df1 <- setDT(df)[order(M_id,Day, Half_hr)][, 
     gr:=gl(.N, 2, .N) , .(M_id ,Day)][] 
dcast(df1, M_id+Day~paste0("Hour_", gr), value.var="Val", sum) 
# M_id Day Hour1 Hour2 
#1: 1000 1 0.35 0.60 
#2: 1000 2 0.90 0.85 
#3: 1001 1 0.35 0.80 
#4: 1001 2 1.10 1.05 
+0

Предполагает ли это 'Half_hr' заказана –

+0

@ RomanLuštrik я предположил, что раньше, но после того, как ваш комментарий' order'ed – akrun

3

Вот решение в базе R, используя transform(), aggregate() и reshape():

reshape(aggregate(Val~.,transform(df,Hour=(Half_hr-1L)%/%2L+1L,Half_hr=NULL),sum),dir='w',idvar=c('M_id','Day'),timevar='Hour'); 
## M_id Day Val.1 Val.2 
## 1 1000 1 0.35 0.60 
## 2 1001 1 0.35 0.80 
## 3 1000 2 0.90 0.85 
## 4 1001 2 1.10 1.05 
+0

Его работа отличная, но сравнительно с моими данными. Огромное спасибо. –

Смежные вопросы