2012-10-30 44 views
5

tôi đang làm việc với một dataframe trông như thế này:Số quan sát bởi ngày trong R

date<-c("2012-02-01", "2012-02-01", "2012-02-03", "2012-02-04", "2012-02-04", "2012-02-05", "2012-02-09", "2012-02-12", "2012-02-12") 
var<-c("a","b","c","d","e","f","g","h","i") 
df1<-data.frame(date,var) 

Tôi muốn tạo ra một dataframe thứ hai mà sẽ lập bảng số quan sát tôi có mỗi ngày. Trong dataframe rằng, ngày đó không được đề cập sẽ nhận được một số không ... dẫn đến một cái gì đó như thế này:

date<-c("2012-02-01","2012-02-02","2012-02-03","2012-02-04","2012-02-05","2012-02-06","2012-02-07","2012-02-08","2012-02-09","2012-02-10","2012-02-11","2012-02-12") 
num<-c(2,0,1,2,1,0,0,0,1,0,0,2) 
df2<-data.frame(date,num) 

Tôi đã thử một số điều với hàm tổng hợp, nhưng không thể tìm ra cách để bao gồm các ngày không có quan sát (số không).

+0

+1 cho một ví dụ tái sản xuất! – mnel

Trả lời

2

Dưới đây là một cách tiếp cận sử dụng data.table

library(data.table) 
DF1 <- as.data.table(df1) 
# coerce date to a date object 
DF1[, date := as.IDate(as.character(date), format = '%Y-%m-%d')] 
# setkey for joining 
setkey(DF1, date) 

# create a data.table that matches with a data.table containing 
# a sequence from the minimum date to the maximum date 
# nomatch = NA includes those non-matching. 
# .N is the number of rows in the subset data.frame 
# this is 0 when there are no matches 
DF2 <- DF1[J(DF1[,seq(min(date), max(date), by = 1)]), .N, nomatch = NA] 
DF2 

      date N 
1: 2012-02-01 2 
2: 2012-02-02 0 
3: 2012-02-03 1 
4: 2012-02-04 2 
5: 2012-02-05 1 
6: 2012-02-06 0 
7: 2012-02-07 0 
8: 2012-02-08 0 
9: 2012-02-09 1 
10: 2012-02-10 0 
11: 2012-02-11 0 
12: 2012-02-12 2 

cách tiếp cận Một sử dụng reshape2::dcast

Nếu bạn đảm bảo rằng cột date của bạn có mức cho mỗi ngày mà bạn muốn chia loại

df1$date <- with(df1, factor(date, levels = as.character(seq(min(as.Date(as.character(date))), max(as.Date(as.character(date))), by = 1)))) 


df2 <- dcast(df1, date~., drop = FALSE) 
+0

+1 Câu trả lời hay. Nhưng tại sao 'by = 1'? –

+0

Đây là một phần của cuộc gọi đến seq. – mnel

+1

Rất tiếc, đôi mắt rực rỡ sáng nay;) –

0

Gần đây tôi đã xử lý điều gì đó l ike này. Tôi sẽ tạo một khung dữ liệu với tất cả các ngày bạn muốn xem xét và sử dụng chức năng merge() để làm những gì bạn đang đề xuất.

df1$date <- as.Date(df1$date, format = "%Y-%m-%d") 
newdates <- data.frame(date=seq(as.Date('2012-02-01'),as.Date('2012-02-12'),1)) 
df2 <- merge(df1, newdates, by = "date", all = TRUE) 

Các all = TRUE là rất quan trọng ở đây, nó giới thiệu NA là nơi df1df2 không phù hợp thay vì xóa những trường hợp này.

Sau đó sử dụng gói plyr để có được đếm:

library(plyr) 
ddply(df2, "date", function(x) sum(!is.na(x$var))) 

này chia df2 thành các nhóm bởi các giá trị độc đáo của df2$date, sau đó phát hiện có bao nhiêu giá trị của df2$var không NA, sau đó trả về con số đó cùng với sự độc đáo giá trị của df2$date nó đại diện.

0

Nhận chỉ số của bạn sang định dạng Postxct, sau đó:

counts <- data.frame(table(as.Date(index(my_data_frame))))

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