2012-04-03 31 views
14

Tôi đang vật lộn với những điều sau đây.R: Tìm và thêm các hàng bị thiếu (/ không tồn tại) trong khung dữ liệu liên quan đến thời gian

Nếu có một (lớn) khung dữ liệu như sau:

  • nhiều cột mà sự kết hợp của các cột là sự kết hợp 'độc đáo', nói ID
  • một thời gian liên quan đến cột
  • một thước đo cột liên quan

Tôi muốn đảm bảo rằng đối với mỗi ID duy nhất cho mỗi khoảng thời gian, một biện pháp có sẵn trong khung dữ liệu. Và nếu không, tôi muốn thêm một biện pháp 0 (hoặc NA) cho thời gian/ID đó.

Để minh họa cho vấn đề, tạo khung test dữ liệu sau:

test <- data.frame(
    YearWeek =rep(c("2012-01","2012-02"),each=4), 
    ProductID =rep(c(1,2), times=4), 
    CustomerID =rep(c("a","b"), each=2, times=2), 
    Quantity =5:12 
)[1:7,] 

    YearWeek ProductID CustomerID Quantity 
1 2012-01   1   a  5 
2 2012-01   2   a  6 
3 2012-01   1   b  7 
4 2012-01   2   b  8 
5 2012-02   1   a  9 
6 2012-02   2   a  10 
7 2012-02   1   b  11 

Hàng thứ 8 được bỏ qua, có mục đích. Bằng cách này tôi mô phỏng một 'giá trị thiếu' (thiếu Quantity) cho ID '2-b' (ProductID-CustomerID) cho giá trị thời gian "2012-02".

Điều tôi muốn làm là điều chỉnh data.frame theo cách sao cho tất cả các giá trị thời gian (được biết, trong ví dụ này chỉ là "2012-01" và "2012-02"), cho tất cả ID- các kết hợp (chúng không được biết trước, nhưng đây là 'tất cả các kết hợp ID duy nhất trong khung dữ liệu', do đó tập hợp duy nhất trên cột ID), một Số lượng có sẵn trong khung dữ liệu.

này nên kết quả ví dụ này (nếu chúng ta chọn NA cho giá trị còn thiếu, điển hình là tôi muốn có quyền kiểm soát trên đó):

YearWeek ProductID CustomerID Quantity 
1 2012-01   1   a  5 
2 2012-01   2   a  6 
3 2012-01   1   b  7 
4 2012-01   2   b  8 
5 2012-02   1   a  9 
6 2012-02   2   a  10 
7 2012-02   1   b  11 
8 2012-02   2   b  NA 

Mục tiêu cuối cùng là tạo ra chuỗi thời gian cho những kết hợp ID và Do đó, tôi muốn có Số lượng cho mọi giá trị thời gian. Tôi cần phải thực hiện các kết hợp khác nhau (đúng giờ) và sử dụng các cấp ID khác nhau từ tập dữ liệu lớn

Tôi đã thử một số thứ, ví dụ: meltcast từ gói reshape. Nhưng cho đến nay tôi đã không quản lý để làm điều đó. Bước tiếp theo là tạo một hàm, với các vòng lặp ... nhưng điều đó không thực sự hữu ích từ một phối cảnh hiệu suất.

Có thể có cách dễ dàng hơn để tạo chuỗi thời gian ngay lập tức, cung cấp dữ liệu.máy như test. Có ai có ý tưởng về cái này không ??

Cảm ơn trước!

Lưu ý rằng trong vấn đề thực tế, có nhiều hơn hai 'cột ID'.


EDIT:

tôi nên mô tả các vấn đề tiếp theo. Có sự khác biệt giữa cột 'thời gian' và cột 'ID'. Câu trả lời đầu tiên (và tuyệt vời!) Về câu hỏi của joran, có thể không hiểu rõ những gì tôi muốn (và ví dụ tôi đưa ra không tạo ra sự khác biệt rõ ràng).Tôi đã nói ở trên:

cho tất cả ID-kết hợp (những thứ này không biết trả trước, nhưng điều này là 'tất cả kết hợp độc đáo ID trong khung dữ liệu', do đó các thiết lập duy nhất trên cột ID)

Vì vậy, tôi không muốn 'tất cả các kết hợp ID có thể' nhưng 'tất cả các kết hợp ID trong dữ liệu'. Đối với mỗi kết hợp đó, tôi muốn có giá trị cho mỗi giá trị thời gian duy nhất.

Hãy để tôi làm cho nó rõ ràng bằng cách mở rộng test-test2, như sau

> test2 <- rbind(test, c("2012-02", 3, "a", 13)) 
> test2 
    YearWeek ProductID CustomerID Quantity 
1 2012-01   1   a  5 
2 2012-01   2   a  6 
3 2012-01   1   b  7 
4 2012-01   2   b  8 
5 2012-02   1   a  9 
6 2012-02   2   a  10 
7 2012-02   1   b  11 
8 2012-02   3   a  13 

Có nghĩa là tôi muốn trong khung dữ liệu kết quả không có sự kết hợp ID '3-b', bởi vì sự kết hợp này không nằm trong test2. Nếu tôi sử dụng phương pháp của câu trả lời đầu tiên tôi sẽ nhận được những điều sau đây:

> vals2 <- expand.grid(YearWeek = unique(test2$YearWeek), 
         ProductID = unique(test2$ProductID), 
         CustomerID = unique(test2$CustomerID)) 

> merge(vals2,test2,all = TRUE) 
    YearWeek ProductID CustomerID Quantity 
1 2012-01   1   a  5 
2 2012-01   1   b  7 
3 2012-01   2   a  6 
4 2012-01   2   b  8 
5 2012-01   3   a  <NA> 
6 2012-01   3   b  <NA> 
7 2012-02   1   a  9 
8 2012-02   1   b  11 
9 2012-02   2   a  10 
10 2012-02   2   b  <NA> 
11 2012-02   3   a  13 
12 2012-02   3   b  <NA> 

Vì vậy, tôi không muốn các hàng 612 có mặt ở đây.

Để khắc phục sự cố này, tôi đã tìm thấy giải pháp trong giải pháp bên dưới. Ở đây tôi chia 'cột thời gian duy nhất' và 'kết hợp ID duy nhất'. Sự khác biệt với ở trên là từ 'kết hợp' và không phải là duy nhất cho mỗi cột ID.

> temp_merge <- merge(unique(test2["YearWeek"]), 
         unique(test2[c("ProductID", "CustomerID")])) 

> merge(temp_merge,test2,all = TRUE) 
    YearWeek ProductID CustomerID Quantity 
1 2012-01   1   a  5 
2 2012-01   1   b  7 
3 2012-01   2   a  6 
4 2012-01   2   b  8 
5 2012-01   3   a  <NA> 
6 2012-02   1   a  9 
7 2012-02   1   b  11 
8 2012-02   2   a  10 
9 2012-02   2   b  <NA> 
10 2012-02   3   a  13 

Nhận xét trên trang này là gì?

Đây có phải là cách thanh lịch hoặc có cách nào tốt hơn không?

Trả lời

20

Sử dụng expand.gridmerge:

vals <- expand.grid(YearWeek = unique(test$YearWeek), 
        ProductID = unique(test$ProductID), 
        CustomerID = unique(test$CustomerID)) 
> merge(vals,test,all = TRUE) 
    YearWeek ProductID CustomerID Quantity 
1 2012-01   1   a  5 
2 2012-01   1   b  7 
3 2012-01   2   a  6 
4 2012-01   2   b  8 
5 2012-02   1   a  9 
6 2012-02   1   b  11 
7 2012-02   2   a  10 
8 2012-02   2   b  NA 

Các NA s có thể được thay thế sau khi thực tế với giá trị nào bạn chọn sử dụng Subsetting và is.na.

+0

+1 đẹp ... –

+0

+1 cho tốc độ và cho 'expand.grid()' mà bạn phải yêu. Đôi khi tôi đã sử dụng nó kết hợp với 'mapply()' hoặc 'plyr :: maply()', như một công cụ để xây dựng tất cả các kết hợp các đối số được truyền cho hai hàm đó. Có ai khác làm điều đó, hoặc là có một thành ngữ tốt hơn? –

+0

@ JoshO'Brien - đó là cùng một phương pháp tôi đã sử dụng quá khứ và đã khá hài lòng với hiệu suất. Tôi rất vui khi thấy thứ gì đó mặc dù vậy. – Chase

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