2015-01-28 18 views
7

Đây là khung dữ liệu ban đầu của tôi:R: Làm thế nào để tổng hợp dựa trên nhiều tiêu chí và tóm tắt bảng

df <- read.table(text=" 
    Date   Index Event 
    2014-03-31 A  x 
    2014-03-31 A  x 
    2014-03-31 A  y 
    2014-04-01 A  y 
    2014-04-01 A  x 
    2014-04-01 B  x 
    2014-04-02 B  x 
    2014-04-03 A  x 
    2014-09-30 B  x", header = T, stringsAsFactors = F) 

date_range <- seq(as.Date(min(df$Date)), as.Date(max(df$Date)), 'days') 
indices <- unique(df$Index) 
events_table <- unique(df$Event) 

Tôi muốn đầu ra mong muốn của tôi để tóm tắt dataframe của tôi và có một hồ sơ duy nhất cho mỗi chỉ số trong chỉ số và mỗi ngày trong date_range trong khi cung cấp giá trị cộng dồn của mỗi sự kiện trong các sự kiện_trong cột mới cho tất cả các ngày trước giá trị trong cột Ngày. Đôi khi không có hồ sơ cho mỗi chỉ mục hoặc mỗi ngày.

Dưới đây là đầu ra mong muốn của tôi:

Date  Index cumsum(Event = x) cumsum(Event = y) 
2014-03-31 A  0     0 
2014-03-31 B  0     0 
2014-04-01 A  2     1 
2014-04-01 B  0     0 
2014-04-02 A  3     2 
2014-04-02 B  1     0 
... 
2014-09-29 A  4     2 
2014-09-29 B  2     0 
2014-09-30 A  4     2 
2014-09-30 B  2     0 

FYI - đây là một phiên bản đơn giản của khung dữ liệu. Có ~ 200.000 bản ghi mỗi năm với hàng trăm trường chỉ mục khác nhau cho mỗi ngày.

Tôi đã làm điều này trong quá khứ trước khi ổ đĩa cứng của tôi chiên bằng cách sử dụng by và có lẽ aggregate, nhưng quá trình này rất chậm và tôi không thể làm cho nó hoạt động trong khoảng thời gian này. Tôi cũng đã thử ddply, nhưng tôi không thể nhận được chức năng cumsum để làm việc với nó. Sử dụng ddply, tôi đã thử một cái gì đó như:

ddply(xo1, .(Date,Index), summarise, 
     sum.x = sum(Event == 'x'), 
     sum.y = sum(Event == 'y')) 

không có kết quả.
Thông qua tìm kiếm, tôi đã tìm thấy Replicating an Excel SUMIFS formula giúp tôi tích lũy dự án của mình, nhưng với điều này tôi đã không thể tìm ra cách tóm tắt chỉ xuống một bản ghi cho mỗi ngày/chỉ mục kết hợp. Tôi cũng đã xem qua số sum/aggregate data based on dates, R nhưng ở đây tôi không thể tìm ra khía cạnh ngày động.

Cảm ơn bất kỳ ai có thể trợ giúp!

+0

Tôi nhầm lẫn với kết quả mong đợi của bạn. Trong một hàng đầu ra mong đợi của bạn, bạn mong đợi 'cumsum (Event = x)' là '0'? Mặc dù 'df' ban đầu của bạn có 2 hàng với' Date = 2014-03-31', 'Index = A' và' Event = x'? – davechilders

+0

Thêm nhấn mạnh "Tôi muốn kết quả mong muốn để tóm tắt dataframe và có bản ghi duy nhất cho mỗi chỉ mục trong chỉ mục và mỗi ngày trong date_range trong khi cung cấp giá trị tích lũy của mỗi sự kiện trong events_table trong cột mới ** cho tất cả các ngày trước Cột ngày ** " ...... Đối với nền, tôi đang cố gắng xây dựng mô hình bằng cách sử dụng thông tin đã có sẵn cho tôi vào sáng hôm đó. Vì vậy, vào sáng ngày 2014-03-31, tôi không có sẵn dữ liệu.Trong suốt cả ngày, dữ liệu được thu thập và vào ngày 2014-04-01, dữ liệu từ 2014-03-31 là những gì tôi sẽ có sẵn để dự đoán sự kiện vào ngày 2014-04-01 – exhoosier10

+0

Cảm ơn bạn đã làm rõ. Tôi đã bỏ lỡ điều đó trong lần đọc đầu tiên của tôi. – davechilders

Trả lời

3
library(dplyr) 
library(tidyr) 

df$Date <- as.Date(df$Date) 

Bước 1: Tạo một danh sách đầy đủ {Date, Index} cặp

full_dat <- expand.grid(
    Date = date_range, 
    Index = indices, 
    stringsAsFactors = FALSE 
) %>% 
    arrange(Date, Index) %>% 
    tbl_df 

Bước 2: Xác định một hàm cumsum() mà bỏ qua NA

cumsum2 <- function(x){ 

    x[is.na(x)] <- 0 
    cumsum(x) 

} 

Bước 3 : Tạo tổng số cho mỗi {Date, Index}, kết hợp với dữ liệu {Date, Index} đầy đủ, và tính toán l tổng tích luỹ.

df %>% 
    group_by(Date, Index) %>% 
    summarise(
    totx = sum(Event == "x"), 
    toty = sum(Event == "y") 
    ) %>% 
    right_join(full_dat, by = c("Date", "Index")) %>% 
    group_by(Index) %>% 
    mutate(
    cumx = lag(cumsum2(totx)), 
    cumy = lag(cumsum2(toty)) 
    ) %>% 
    # some clean up. 
    select(-starts_with("tot")) %>% 
    mutate(
    cumx = ifelse(is.na(cumx), 0, cumx), 
    cumy = ifelse(is.na(cumy), 0, cumy) 
    ) 
+0

rực rỡ. mất <10 giây cho những hàng 200k này. Đánh giá cao sự giúp đỡ của bạn! – exhoosier10

1

Điều gì đó tương tự bằng cách sử dụng dplyrtidyr có hoạt động không?

library(dplyr) 
library(tidyr) 

df %>% 
    group_by(Date, Index, Event) %>% 
    summarise(events = n()) %>% 
    group_by(Index, Event) %>% 
    mutate(cumsum_events = cumsum(events)) %>% 
    select(-events) %>% 
    spread(Event, cumsum_events) %>% 
    rename(sum.x = x, 
     sum.y = y) 

#  Date Index sum.x sum.y 
#1 2014-03-31  A  2  1 
#2 2014-04-01  A  3  2 
#3 2014-04-01  B  1 NA 
#4 2014-04-02  B  2 NA 
#5 2014-04-03  A  4 NA 
#6 2014-09-30  B  3 NA 
+0

Sử dụng thông minh của 'spread()' tại đây. +1 –

+0

Điều này rất hữu ích để tóm tắt mọi thứ, nhờ .... Mục tiêu của tôi là có một bản ghi cho mỗi chỉ mục duy nhất (tất cả chỉ mục) và ngày (ngày từ 2014-03-31 và 2014-09-30) kết hợp để tôi có thể xuất dữ liệu đó thành một tệp riêng lẻ cho mỗi ngày của tất cả dữ liệu của năm đến thời điểm đó. Một số ngày chúng tôi không thu thập thông tin về Chỉ số A, vì vậy nếu tôi tập hợp con theo ngày = '2014-04-02' bằng cách sử dụng phương pháp này, tôi chỉ thấy dữ liệu cho Chỉ số B chứ không phải A. Có cách nào nhanh chóng để nhận mà không cần bổ sung thêm các bản ghi bổ sung cho mỗi khóa Date + Index duy nhất ?? – exhoosier10

+0

@maloneypatr - Tôi không nghĩ rằng giải pháp của bạn phù hợp với sản lượng mong muốn của OP. – davechilders

Các vấn đề liên quan