2013-02-11 27 views
18

Tôi đang sử dụng R để vẽ một số dữ liệu.Ngắt dòng khi không có dữ liệu trong ggplot2

Date <- c("07/12/2012 05:00:00", "07/12/2012 06:00:00", "07/12/2012 07:00:00", 
     "07/12/2012 08:00:00","07/12/2012 10:00:00","07/12/2012 11:00:00") 
Date <- strptime(Date, "%d/%m/%Y %H:%M") 
Counts <- c("0","3","10","6","5","4") 
Counts <- as.numeric(Counts) 
df1 <- data.frame(Date,Counts,stringsAsFactors = FALSE) 
library(ggplot2) 
g = ggplot(df1, aes(x=Date, y=Counts)) + geom_line(aes(group = 1)) 
g 

Làm cách nào để yêu cầu R không vẽ dữ liệu dưới dạng đường liên tục khi có thời gian nghỉ ngơi? Tôi thường có một điểm dữ liệu mỗi giờ, nhưng đôi khi có một break (từ 8 giờ sáng đến 10 giờ sáng). Giữa những điểm này, tôi không muốn đường kết nối. Điều này có thể xảy ra trong R?

Sửa

Rất cám ơn cho những câu trả lời ở đây. Dữ liệu của tôi hiện đang trong khoảng thời gian 10 giây và tôi muốn thực hiện cùng một phân tích bằng cách sử dụng dữ liệu này.

df <- structure(list(Date = c("11/12/2012", "11/12/2012", "11/12/2012", 
        "11/12/2012", "11/12/2012", "11/12/2012", "11/12/2012", 
        "11/12/2012", "11/12/2012", "11/12/2012", "11/12/2012"), 
        Time = c("20:16:00", "20:16:10", "20:16:20", "20:16:30", 
        "20:16:40", "20:16:50", "20:43:30", "20:43:40", 
        "20:43:50", "20:44:00", "20:44:10"), 
        Axis1 = c(181L, 14L, 65L, 79L, 137L, 104L, 7L, 0L, 0L, 
        14L, 0L), 
        Steps = c(13L, 1L, 6L, 3L, 8L, 4L, 1L, 0L, 0L, 0L, 0L)), 
       .Names = c("Date", "Time", "Axis1", "Steps"), 
       row.names = c(57337L, 57338L, 57339L, 57340L, 57341L, 57342L, 
       57502L, 57503L, 57504L, 57505L, 57506L), class = "data.frame") 

Tôi nghĩ rằng tôi hiểu những gì đang cố gắng để làm, khi nó bổ sung thêm cột 'nhóm' đến dataframe gốc, nhưng câu hỏi của tôi xung quanh như thế nào tôi nhận được R để biết các dữ liệu hiện đang ở 10 khoảng thứ hai ? Khi tôi áp dụng dòng đầu tiên của mã để xác định xem các số có liên tục hay không có khoảng trống (ví dụ idx < - c (1, diff (df $ Time)), tôi nhận được lỗi sau:

Lỗi trong r [i1] - r [-length (r) :-(chiều dài (r) - lag + 1L)]: đối số không phải số để toán tử nhị phân

Sau biến 'Thời gian', tôi có cần phải thêm 'as.POSIXct' để đảm bảo nhận ra thời gian chính xác?

Trả lời

15

Bạn sẽ phải đặt group bằng cách đặt giá trị chung cho những điểm bạn muốn được kết nối. Ở đây, bạn có thể đặt 4 giá trị đầu tiên để nói 1 và 2 đếncuối cùng. Và giữ chúng như là các yếu tố. Đó là,

df1$grp <- factor(rep(1:2, c(4,2))) 
g <- ggplot(df1, aes(x=Date, y=Counts)) + geom_line(aes(group = grp)) + 
        geom_point() 

Edit: Một khi bạn có bạn data.frame nạp, bạn có thể sử dụng mã này để tự động tạo ra các grp cột:

idx <- c(1, diff(df$Date)) 
i2 <- c(1,which(idx != 1), nrow(df)+1) 
df1$grp <- rep(1:length(diff(i2)), diff(i2)) 

Lưu ý: Đó là quan trọng để thêm geom_point() cũng vì nếu discontinuous range xảy ra là mục nhập LAST trong data.frame, nó sẽ không được vẽ (vì không có 2 điểm để kết nối đường). Trong trường hợp này, geom_point() sẽ vẽ đồ thị.

Như một ví dụ, tôi sẽ tạo ra một dữ liệu với nhiều khoảng trống:

# get a test data 
set.seed(1234) 
df <- data.frame(Date=seq(as.POSIXct("05:00", format="%H:%M"), 
       as.POSIXct("23:00", format="%H:%M"), by="hours")) 
df$Counts <- sample(19) 
df <- df[-c(4,7,17,18),] 

# generate the groups automatically and plot 
idx <- c(1, diff(df$Date)) 
i2 <- c(1,which(idx != 1), nrow(df)+1) 
df$grp <- rep(1:length(diff(i2)), diff(i2)) 
g <- ggplot(df, aes(x=Date, y=Counts)) + geom_line(aes(group = grp)) + 
      geom_point() 
g 

ggplot2_groups

Edit: Đối với dữ liệu mới của bạn (giả sử nó là df),

df$t <- strptime(paste(df$Date, df$Time), format="%d/%m/%Y %H:%M:%S") 

idx <- c(10, diff(df$t)) 
i2 <- c(1,which(idx != 10), nrow(df)+1) 
df$grp <- rep(1:length(diff(i2)), diff(i2)) 

giờ là âm mưu với aes(x=t, ...).

+0

(+1) Tuy nhiên, trong trường hợp này, nó giống như OP mong đợi các giá trị thiếu trong dữ liệu của anh ta, phải không? :-) – juba

+0

Rất cám ơn. Có cách nào để làm điều này tự động mà không nhìn vào các tập tin dữ liệu cá nhân (như tôi có> 1000 tập tin để chạy theo cách này, và tôi sẽ không có khả năng có thể nhìn vào từng cái một?). Và @ Juba - vâng, tôi mong đợi số không. Trong dữ liệu thực của tôi, nếu có 20 phút số 0 liên tục, chúng sẽ bị xóa. –

+0

Có, miễn là bạn biết rằng khoảng thời gian là luôn luôn 1 giờ, chúng tôi có thể làm điều này. Cho tôi một phút, tôi sẽ chỉnh sửa bài đăng. – Arun

11

Tôi nghĩ rằng không có cách nào cho R hoặc ggplot2 để biết nếu có điểm dữ liệu bị thiếu ở đâu đó, ngoài bạn chỉ định nó với một NA.Bằng cách này, ví dụ:

df1 <- rbind(df1, list(strptime("07/12/2012 09:00:00", "%d/%m/%Y %H:%M"), NA)) 
ggplot(df1, aes(x=Date, y=Counts)) + geom_line(aes(group = 1)) 

enter image description here

+0

(+1) tuy nhiên, trong trường hợp này, nó giống như OP mong đợi hai nhóm lô, phải không? Ý tôi là, không thích hợp hơn khi đặt nhóm KHÔNG thành 1, thay vì một biến nhóm ... – Arun

+0

@Arun Vâng, tôi không biết, tôi không thấy nó theo cách đó, nhưng bạn có thể đúng ... – juba

3

Juba's answer, bao gồm rõ ràng NA 's nơi bạn muốn phá vỡ, là cách tiếp cận tốt nhất. Dưới đây là một cách thay thế để giới thiệu những người NA 's ở đúng nơi (mà không cần phải tìm ra nó bằng tay).

every.hour <- data.frame(Date=seq(min(Date), max(Date), by="1 hour")) 
df2 <- merge(df1, every.hour, all=TRUE) 
g %+% df2 

enter image description here

Bạn có thể làm điều gì đó tương tự với sau df ví dụ của bạn, sau khi thay đổi ngày tháng và thời gian sang một định dạng thích hợp

df$DateTime <- as.POSIXct(strptime(paste(df$Date, df$Time), 
            format="%m/%d/%Y %H:%M:%S")) 
every.ten.seconds <- data.frame(DateTime=seq(min(df$DateTime), 
              max(df$DateTime), by="10 sec")) 
df.10 <- merge(df, every.ten.seconds, all=TRUE) 
Các vấn đề liên quan