2017-05-18 4 views
1

해결책보다 쉬운 것은 왜 쉬운지를 이해하고 싶습니다. 실제로는 그렇지 않습니다.ggplot2 : yearmon scale 및 geom_bar

[나는이 문제에 감동을 다른 게시물에서 코드의 일부를 차용하고 있지만, 내가 좋아하지 않는 해결책을 마감]

library(ggplot2) 
library(xts) 
library(dplyr) 
library(scales) 

csvData <- "dt,status 
2015-12-03,1 
2015-12-05,1 
2015-12-05,0 
2015-11-24,1 
2015-10-17,0 
2015-12-18,0 
2016-06-30,0 
2016-05-21,1 
2016-03-31,0 
2015-12-31,0" 

tmp <- read.csv(textConnection(csvData)) 
tmp$dt <- as.Date(tmp$dt) 
tmp$yearmon <- as.yearmon(tmp$dt) 
tmp$status <- as.factor(tmp$status) 

### Not good. Why? 
ggplot(tmp, aes(x = yearmon, fill = status)) + 
    geom_bar() + 
    scale_x_yearmon() 

### Almost good but long-winded and ticks not great 
chartData <- tmp %>% 
    group_by(yearmon, status) %>% 
    summarise(count = n()) %>% 
    as.data.frame() 
ggplot(chartData, aes(x = yearmon, y = count, fill = status)) + 
    geom_col() + 
    scale_x_yearmon() 

첫 번째 플롯은 모든 잘못; 두 번째는 거의 완벽합니다. (X 축의 눈금은 크지 않지만 그와 함께 살 수 있습니다). geom_bar() 카운트 작업을 수행해야하는데 두 번째 차트에서 수동으로 수행해야합니까?

FIRST 차트 poor plot

SECOND 차트 better plot

내 질문은 왜 첫 번째 차트는 가난하다? 뭔가를 제안하기위한 경고가 있습니다 ("position_stack은 겹치지 않는 x 간격을 필요로합니다). 그러나 나는 그것을 이해하지 못합니다. 감사합니다. .

내 개인 응답

이 내가 배운 것입니다 (여러분 모두 너무 많은 감사를!)하십시오 scale_#_yearmon 또는 scale_#_date, 불행하게도 ggplot 취급 사람들이

  • 하더라도 연속 번호로 개체 유형. 따라서 geom_bar을 사용할 수 없게됩니다.
  • geom_histogram 트릭을 수행 할 수 있습니다. 그러나 당신은 aestethics의 관련 부분에 대한 통제권을 잃게됩니다.
  • 결론은 : 당신이 그룹에 필요/합계 당신이 XTS 또는 lubridate (당신이 ggplot2를 사용하려는 경우)
  • 확실하지 차트 정말 달성하기 위해 노력하고 있었는지에 대한 그 유용하기 전에. 나는 어떤 연속적인 사건도 용의자가 - 날짜 - 현명한 - 그들은 완벽 할 것입니다.

    library(ggplot2) 
    library(dplyr) 
    library(scales) 
    
    csvData <- "dt,status 
    2015-12-03,1 
    2015-12-05,1 
    2015-12-05,0 
    2015-11-24,1 
    2015-10-17,0 
    2015-12-18,0 
    2016-06-30,0 
    2016-05-21,1 
    2016-03-31,0 
    2015-12-31,0" 
    
    tmp <- read.csv(textConnection(csvData)) 
    tmp$dt <- as.Date(tmp$dt) 
    tmp$yearmon <- as.Date(format(tmp$dt, "%Y-%m-01")) 
    tmp$status <- as.factor(tmp$status) 
    
    ### GOOD 
    chartData <- tmp %>% 
        group_by(yearmon, status) %>% 
        summarise(count = n()) %>% 
        as.data.frame() 
    
    ggplot(chartData, aes(x = yearmon, y = count, fill = status)) + 
        geom_col() + 
        scale_x_date(labels = date_format("%h-%y"), 
           breaks = seq(from = min(chartData$yearmon), 
              to = max(chartData$yearmon), by = "month")) 
    

    최종 출력 final plot :

모든에서, 나는 내가 뭘 후 오전 (XTS 또는 lubridate에 대한 필요가 없습니다 어떻게 알) 완벽 않는이 끝났다

+0

첫 번째 플롯과 두 번째 플롯간에 차이점이 없습니다. 플롯의 이미지를 게시하고 첫 번째 줄거리에 대한 잘못된 점을 지적 할 수 있습니까? –

+0

요청한대로 완료. 플랫폼/패키지 버전에서 문제가 될 수 있습니까? 나는 WIN10에있다. R 버전 3.4.0 (2017-04-21); ggplot2 2.2.1 –

+0

ggplot (tmp, aes (x = floor_date (dt, "month"), fill = status)) + geom_bar() + scale_x_date (labels = date_format ("% Y- % b ")), 더 나은 x 축을 제공합니다. –

답변

1

첫 번째 플롯이 망가지는 이유는 기본적으로 ggplot2이 정확히 무엇입니까 yearmon은입니다. 여기에서 알 수 있듯이 라벨은 내부적으로는 num입니다.

> as.numeric(tmp$yearmon) 
[1] 2015.917 2015.917 2015.917 2015.833 2015.750 2015.917 2016.417 2016.333 2016.167 2015.917 

이전 집계없이 플롯하면 막대가 펼쳐집니다.이 같은 geom_histogram()를 사용 binwidth 적절한 할당해야합니다 :

ggplot(tmp, aes(x = yearmon, fill = status)) + 
    geom_histogram(binwidth = 1/12) + 
    scale_x_yearmon() 

1/12 매년 12 개월에 해당합니다.

@ed_sans가 제안한대로 집계 후의 플롯의 경우 틱을 변경하고 축 레이블을 수정하는 방법에 대해 더 잘 알고 있으므로 lubridate을 선호합니다.

chartData <- tmp %>% 
    mutate(ym = floor_date(dt,"month")) %>% 
    group_by(ym, status) %>% 
    summarise(count = n()) %>% 
    as.data.frame() 

ggplot(chartData, aes(x = ym, y = count, fill = status)) + 
    geom_col() + 
    scale_x_date(labels = date_format("%Y-%m"), 
       breaks = as.Date("2015-09-01") + 
       months(seq(0, 10, by = 2)))