ggplot với 2 trục y ở mỗi bên và quy mô khác nhau


231

Tôi cần vẽ biểu đồ thanh hiển thị số đếm và biểu đồ đường hiển thị tỷ lệ tất cả trong một biểu đồ, tôi có thể thực hiện cả hai biểu đồ một cách riêng biệt, nhưng khi tôi đặt chúng lại với nhau, tôi chia tỷ lệ của lớp đầu tiên (nghĩa là geom_bar) bị chồng chéo bởi lớp thứ hai lớp (tức là geom_line).

Tôi có thể di chuyển trục của geom_linebên phải không?


5
Bạn có thể sử dụng một cách tiếp cận như shwon ở đây không, rpub.com/kohske/dual_axis_in_ggplot2 ?
Tom Wenseleers 17/08/2015


2
cuộn xuống để xem ggplot2triển khai riêng bên trong scale_y_*, hiện được gọi sec.axis.
PatrickT

Câu trả lời:


106

Đôi khi một khách hàng muốn hai thang đo y. Cung cấp cho họ bài phát biểu "thiếu sót" thường là vô nghĩa. Nhưng tôi thích ggplot2 khăng khăng làm mọi thứ đúng cách. Tôi chắc chắn rằng ggplot trên thực tế đang giáo dục người dùng trung bình về các kỹ thuật hình dung phù hợp.

Có lẽ bạn có thể sử dụng faceting và scale free để so sánh hai chuỗi dữ liệu? - ví dụ: xem tại đây: https://github.com/hadley/ggplot2/wiki/Align-two-plots-on-a-page


30
Tôi đồng tình với Andreas - đôi khi (như bây giờ, đối với tôi), một khách hàng muốn có hai bộ dữ liệu trên cùng một cốt truyện và không muốn nghe tôi nói về Lý thuyết âm mưu. Tôi phải thuyết phục họ không muốn điều đó nữa (không phải luôn là trận chiến tôi muốn tiến hành), hoặc nói với họ "gói âm mưu mà tôi đang sử dụng không hỗ trợ điều đó". Vì vậy, hôm nay tôi sẽ chuyển từ ggplot cho dự án cụ thể này. = (
Ken Williams

58
Tại sao một gói âm mưu cần chèn ý kiến ​​cá nhân của riêng mình vào cách thức hoạt động? Không cám ơn.
colin

5
Liên kết của bạn bị mục nát. Bạn có thể chỉnh sửa câu trả lời của bạn và đăng một bản tóm tắt về những gì nó được sử dụng để nói?
Zach

24
Không thể đồng ý với nhận xét này (re rant). Việc ngưng tụ thông tin càng nhiều càng tốt, ví dụ như đưa ra các hạn chế nghiêm ngặt được áp đặt bởi các tạp chí khoa học, v.v., để nhanh chóng đưa ra thông điệp. Do đó, việc thêm một trục y thứ hai vẫn đang được thực hiện và theo tôi, ggplot sẽ giúp tôi làm điều đó.
Cá đuối

57
Thật đáng ngạc nhiên khi những từ không thể nghi ngờ như "thiếu sót" và "đúng cách" được ném ra như thể chúng không dựa trên một lý thuyết mà bản thân nó thực sự khá quan tâm và giáo điều, nhưng được chấp nhận bởi rất nhiều người, có thể được nhìn thấy bởi rất nhiều người thực tế là câu trả lời hoàn toàn không có ích này (ném một liên kết xương) có 72 upvote tại thời điểm viết. Whe so sánh chuỗi thời gian, ví dụ, nó có thể là vô giá để có cả hai trên bảng xếp hạng cùng, bởi vì tương quan của sự khác biệt là dễ dàng hơn nhiều để phát hiện. Chỉ cần hỏi hàng ngàn chuyên gia tài chính có trình độ học vấn cao, những người làm việc này cả ngày mỗi ngày.
Thomas Browne

149

Không thể có trong ggplot2 vì tôi tin rằng các ô có thang đo y riêng biệt (không phải thang đo y là các phép biến đổi của nhau) về cơ bản là thiếu sót. Một số vấn đề:

  • Không thể đảo ngược: được cho một điểm trên không gian lô, bạn không thể ánh xạ duy nhất nó trở lại một điểm trong không gian dữ liệu.

  • Chúng tương đối khó đọc chính xác so với các tùy chọn khác. Xem Nghiên cứu về Biểu đồ dữ liệu quy mô kép của Petra Isenberg, Anastasia Bezerianos, Pierre Dragicevic và Jean-Daniel Fekete để biết chi tiết.

  • Chúng dễ dàng bị thao túng để đánh lừa: không có cách duy nhất để xác định quy mô tương đối của các trục, để chúng mở cho thao tác. Hai ví dụ từ blog Junkcharts: một , hai

  • Chúng là tùy ý: tại sao chỉ có 2 thang đo chứ không phải 3, 4 hay mười?

Bạn cũng có thể muốn đọc cuộc thảo luận dài của Stephen Few về chủ đề Các trục tỷ lệ kép trong đồ thị Chúng có bao giờ là giải pháp tốt nhất không? .


39
Bạn có thể giải thích ý kiến ​​của bạn? Không giác ngộ, tôi nghĩ rằng đó là một cách khá nhỏ gọn để vẽ hai biến độc lập. Nó cũng là một tính năng dường như được yêu cầu và nó được sử dụng rộng rãi.
KarlP

66
@hadley: Hầu hết tôi đồng ý, nhưng có một cách sử dụng chính xác cho nhiều thang đo y - việc sử dụng 2 đơn vị khác nhau cho cùng một dữ liệu, ví dụ: thang đo Celsius và Fahrenheit trên chuỗi thời gian nhiệt độ.
Bông Richie

11
@Hadley Theo ý kiến ​​của bạn. Không phải trong tôi, cũng không nhiều nhà khoa học khác. Chắc chắn điều này có thể đạt được bằng cách đặt một cốt truyện thứ hai (với nền hoàn toàn trong suốt) trực tiếp trên cái thứ nhất, để chúng xuất hiện như một. Tôi chỉ không biết làm thế nào để đảm bảo các góc của khung giới hạn được căn chỉnh / đăng ký với nhau.
Nicholas Hamilton

8
@hadley Ví dụ, trong Sơ đồ khí hậu Walther-Lieth , hai trục y thường được sử dụng. Vì có một đơn thuốc cố định làm thế nào để làm điều đó có thể gây nhầm lẫn là tối thiểu ...
sebschub

32
@hadley Tôi xin lỗi, tôi không thấy có vấn đề gì với sơ đồ khí hậu đã cho. Đặt nhiệt độ và lượng mưa trong một sơ đồ (với đơn thuốc cố định), người ta có thể đoán nhanh trước xem đó là khí hậu ẩm hay khô. Hoặc cách xung quanh: điều gì sẽ là một cách tốt hơn để hình dung nhiệt độ, lượng mưa và "mối quan hệ" của chúng? Dù sao, cảm ơn rất nhiều cho công việc của bạn trong ggplot2!
sebschub

121

Bắt đầu với ggplot2 2.2.0, bạn có thể thêm một trục thứ cấp như thế này (lấy từ thông báo ggplot2 2.2.0 ):

ggplot(mpg, aes(displ, hwy)) + 
  geom_point() + 
  scale_y_continuous(
    "mpg (US)", 
    sec.axis = sec_axis(~ . * 1.20, name = "mpg (UK)")
  )

nhập mô tả hình ảnh ở đây


25
Nhược điểm là, nó chỉ có thể sử dụng một số chuyển đổi công thức của các trục hiện tại không phải là một biến mới, ví dụ.
discipulus

41

Lấy câu trả lời ở trên và một số tinh chỉnh (và cho bất cứ điều gì nó có giá trị), đây là một cách để đạt được hai thang đo thông qua sec_axis:

Giả sử một bộ dữ liệu đơn giản (và hoàn toàn hư cấu) dt: trong năm ngày, nó theo dõi số lần gián đoạn năng suất VS:

        when numinter prod
1 2018-03-20        1 0.95
2 2018-03-21        5 0.50
3 2018-03-23        4 0.70
4 2018-03-24        3 0.75
5 2018-03-25        4 0.60

(phạm vi của cả hai cột khác nhau bởi khoảng 5 yếu tố).

Đoạn mã sau sẽ vẽ cả hai chuỗi mà chúng sử dụng lên toàn bộ trục y:

ggplot() + 
  geom_bar(mapping = aes(x = dt$when, y = dt$numinter), stat = "identity", fill = "grey") +
  geom_line(mapping = aes(x = dt$when, y = dt$prod*5), size = 2, color = "blue") + 
  scale_x_date(name = "Day", labels = NULL) +
  scale_y_continuous(name = "Interruptions/day", 
    sec.axis = sec_axis(~./5, name = "Productivity % of best", 
      labels = function(b) { paste0(round(b * 100, 0), "%")})) + 
  theme(
      axis.title.y = element_text(color = "grey"),
      axis.title.y.right = element_text(color = "blue"))

Đây là kết quả (mã trên + một số điều chỉnh màu):

hai thang đo trong một ggplot2

Điểm (ngoài việc sử dụng sec_axiskhi chỉ định y_scale là nhân mỗi giá trị của chuỗi dữ liệu thứ 2 với 5 khi chỉ định chuỗi. Để có được các nhãn ngay trong định nghĩa sec_axis, sau đó cần chia cho 5 (và định dạng). một phần quan trọng trong mã ở trên thực sự *5nằm trong geom_line và ~./5sec_axis (một công thức chia giá trị hiện tại .cho 5).

Để so sánh (tôi không muốn đánh giá các cách tiếp cận ở đây), đây là cách hai biểu đồ xếp chồng lên nhau trông như sau:

hai biểu đồ trên nhau

Bạn có thể tự đánh giá xem ai sẽ vận chuyển thông điệp tốt hơn (Hãy đừng làm phiền mọi người tại nơi làm việc!). Đoán đó là một cách công bằng để quyết định.

Mã đầy đủ cho cả hai hình ảnh (nó không thực sự nhiều hơn những gì ở trên, chỉ cần hoàn thành và sẵn sàng để chạy) là ở đây: https://gist.github.com/sebastianrothbucher/de847063f32fdff02c83b75f59c36a7d một lời giải thích chi tiết hơn ở đây: https: // seb github.io/datascience/r/visualization/ggplot/2018/03/24/two-scales-ggplot-r.html


31

Có những trường hợp sử dụng phổ biến đấu tay đôi y, ví dụ, khí hậu cho thấy nhiệt độ và lượng mưa hàng tháng. Đây là một giải pháp đơn giản, được khái quát hóa từ giải pháp của Megatron bằng cách cho phép bạn đặt giới hạn dưới của các biến thành một giá trị khác không:

Dữ liệu ví dụ:

climate <- tibble(
  Month = 1:12,
  Temp = c(-4,-4,0,5,11,15,16,15,11,6,1,-3),
  Precip = c(49,36,47,41,53,65,81,89,90,84,73,55)
  )

Đặt hai giá trị sau thành giá trị gần với giới hạn của dữ liệu (bạn có thể chơi xung quanh với các giá trị này để điều chỉnh vị trí của biểu đồ; các trục vẫn sẽ chính xác):

ylim.prim <- c(0, 180)   # in this example, precipitation
ylim.sec <- c(-4, 18)    # in this example, temperature

Sau đây thực hiện các tính toán cần thiết dựa trên các giới hạn này và tự tạo cốt truyện:

b <- diff(ylim.prim)/diff(ylim.sec)
a <- b*(ylim.prim[1] - ylim.sec[1])

ggplot(climate, aes(Month, Precip)) +
  geom_col() +
  geom_line(aes(y = a + Temp*b), color = "red") +
  scale_y_continuous("Precipitation", sec.axis = sec_axis(~ (. - a)/b, name = "Temperature")) +
  scale_x_continuous("Month", breaks = 1:12) +
  ggtitle("Climatogram for Oslo (1961-1990)")  

Climatogram hiển thị nhiệt độ dưới dạng đường và lượng mưa như barplot

Nếu bạn muốn đảm bảo rằng dòng màu đỏ tương ứng với trục y bên phải, bạn có thể thêm một themecâu vào mã:

ggplot(climate, aes(Month, Precip)) +
  geom_col() +
  geom_line(aes(y = a + Temp*b), color = "red") +
  scale_y_continuous("Precipitation", sec.axis = sec_axis(~ (. - a)/b, name = "Temperature")) +
  scale_x_continuous("Month", breaks = 1:12) +
  theme(axis.line.y.right = element_line(color = "red"), 
        axis.ticks.y.right = element_line(color = "red"),
        axis.text.y.right = element_text(color = "red"), 
        axis.title.y.right = element_text(color = "red")
        ) +
  ggtitle("Climatogram for Oslo (1961-1990)")

Màu nào cho trục bên phải:

Climatogram với trục bên phải màu đỏ


Điều này phá vỡ tại một số giá trị của ylim.primylim.sec.
Eric Krantz

5
Điều đó thật tuyệt. Ví dụ hay khi biểu đồ hai trục không "thiếu sót". Một phần của tâm lý gọn gàng chung về suy nghĩ họ biết nhiều về công việc của bạn hơn bạn.
Leo Barlach

Khi tôi chọn giới hạn trục cụ thể (trong trường hợp của tôi là ylim.prim <- c (90, 130) và ylim.sec <- c (15, 30)), nó không áp dụng nó mà chọn giới hạn tùy ý, làm rối tung mọi thang đo . Tôi không chắc chắn những gì tôi thiếu khi tôi sao chép mã ở trên và chỉ thay đổi tên biến và giới hạn trục
Anke

@anke: văn bản có phần cẩu thả khi đề cập đến ylim.prim và ylim.sec. Họ không đề cập đến các giới hạn của trục, mà là các giới hạn của dữ liệu của bạn. Khi bạn đặt ylim.prim <- c (90, 130) và ylim.sec <- c (15, 30) như bạn đã đề cập, biểu đồ nhiệt độ kết thúc ở trên cao trên biểu đồ thanh (vì trục nhiệt độ bắt đầu ở -75) , nhưng các trục cho mỗi biểu đồ vẫn đúng.
Dag Hjermann

16

Bạn có thể tạo một hệ số tỷ lệ được áp dụng cho geom thứ hai và trục y bên phải. Điều này được bắt nguồn từ giải pháp của Sebastian.

library(ggplot2)

scaleFactor <- max(mtcars$cyl) / max(mtcars$hp)

ggplot(mtcars, aes(x=disp)) +
  geom_smooth(aes(y=cyl), method="loess", col="blue") +
  geom_smooth(aes(y=hp * scaleFactor), method="loess", col="red") +
  scale_y_continuous(name="cyl", sec.axis=sec_axis(~./scaleFactor, name="hp")) +
  theme(
    axis.title.y.left=element_text(color="blue"),
    axis.text.y.left=element_text(color="blue"),
    axis.title.y.right=element_text(color="red"),
    axis.text.y.right=element_text(color="red")
  )

nhập mô tả hình ảnh ở đây

Lưu ý: sử dụng ggplot2 v3.0.0


14

Xương sống kỹ thuật cho giải pháp của thách thức này đã được Kohske cung cấp khoảng 3 năm trước [ KOHSKE ]. Chủ đề và các kỹ thuật xung quanh giải pháp của nó đã được thảo luận về một số trường hợp ở đây trên Stackoverflow [ID: 18989001, 29235405, 21026598]. Vì vậy, tôi sẽ chỉ cung cấp một biến thể cụ thể và một số hướng dẫn giải thích, sử dụng các giải pháp trên.

Giả sử chúng ta có một số dữ liệu y1 trong nhóm G1 mà một số dữ liệu y2 trong nhóm G2 có liên quan theo một cách nào đó, ví dụ như phạm vi / tỷ lệ được chuyển đổi hoặc có thêm một số nhiễu. Vì vậy, người ta muốn vẽ dữ liệu cùng nhau trên một ô với tỷ lệ y1 ở bên trái và y2 ở bên phải.

  df <- data.frame(item=LETTERS[1:n],  y1=c(-0.8684, 4.2242, -0.3181, 0.5797, -0.4875), y2=c(-5.719, 205.184, 4.781, 41.952, 9.911 )) # made up!

> df
  item      y1         y2
1    A -0.8684 -19.154567
2    B  4.2242 219.092499
3    C -0.3181  18.849686
4    D  0.5797  46.945161
5    E -0.4875  -4.721973

Nếu bây giờ chúng ta vẽ dữ liệu của mình cùng với một cái gì đó như

ggplot(data=df, aes(label=item)) +
  theme_bw() + 
  geom_segment(aes(x='G1', xend='G2', y=y1, yend=y2), color='grey')+
  geom_text(aes(x='G1', y=y1), color='blue') +
  geom_text(aes(x='G2', y=y2), color='red') +
  theme(legend.position='none', panel.grid=element_blank())

nó không phù hợp độc đáo khi quy mô nhỏ hơn y1 bị sụp đổ bởi quy mô y2 lớn hơn .

Mẹo ở đây để đáp ứng thách thức là về mặt kỹ thuật vẽ cả hai tập dữ liệu theo thang đo y1 đầu tiên nhưng báo cáo lần thứ hai theo trục thứ cấp với các nhãn hiển thị thang đo y2 ban đầu .

Vì vậy, chúng tôi xây dựng một hàm trợ giúp đầu tiên là CalcFudgeAxis để tính toán và thu thập các tính năng của trục mới sẽ được hiển thị. Hàm này có thể được sửa đổi thành ayones thích (cái này chỉ ánh xạ y2 vào phạm vi của y1 ).

CalcFudgeAxis = function( y1, y2=y1) {
  Cast2To1 = function(x) ((ylim1[2]-ylim1[1])/(ylim2[2]-ylim2[1])*x) # x gets mapped to range of ylim2
  ylim1 <- c(min(y1),max(y1))
  ylim2 <- c(min(y2),max(y2))    
  yf <- Cast2To1(y2)
  labelsyf <- pretty(y2)  
  return(list(
    yf=yf,
    labels=labelsyf,
    breaks=Cast2To1(labelsyf)
  ))
}

những gì mang lại một số:

> FudgeAxis <- CalcFudgeAxis( df$y1, df$y2 )

> FudgeAxis
$yf
[1] -0.4094344  4.6831656  0.4029175  1.0034664 -0.1009335

$labels
[1] -50   0  50 100 150 200 250

$breaks
[1] -1.068764  0.000000  1.068764  2.137529  3.206293  4.275058  5.343822


> cbind(df, FudgeAxis$yf)
  item      y1         y2 FudgeAxis$yf
1    A -0.8684 -19.154567   -0.4094344
2    B  4.2242 219.092499    4.6831656
3    C -0.3181  18.849686    0.4029175
4    D  0.5797  46.945161    1.0034664
5    E -0.4875  -4.721973   -0.1009335

Bây giờ tôi đã bọc giải pháp của Kohske trong hàm trợ giúp thứ hai PlotWithFudgeAxis (trong đó chúng ta ném đối tượng ggplot và đối tượng trợ giúp của trục mới):

library(gtable)
library(grid)

PlotWithFudgeAxis = function( plot1, FudgeAxis) {
  # based on: https://rpubs.com/kohske/dual_axis_in_ggplot2
  plot2 <- plot1 + with(FudgeAxis, scale_y_continuous( breaks=breaks, labels=labels))

  #extract gtable
  g1<-ggplot_gtable(ggplot_build(plot1))
  g2<-ggplot_gtable(ggplot_build(plot2))

  #overlap the panel of the 2nd plot on that of the 1st plot
  pp<-c(subset(g1$layout, name=="panel", se=t:r))
  g<-gtable_add_grob(g1, g2$grobs[[which(g2$layout$name=="panel")]], pp$t, pp$l, pp$b,pp$l)

  ia <- which(g2$layout$name == "axis-l")
  ga <- g2$grobs[[ia]]
  ax <- ga$children[[2]]
  ax$widths <- rev(ax$widths)
  ax$grobs <- rev(ax$grobs)
  ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
  g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1)
  g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)

  grid.draw(g)
}

Bây giờ tất cả có thể được đặt cùng nhau: Dưới đây mã cho thấy, làm thế nào giải pháp đề xuất có thể được sử dụng trong môi trường hàng ngày . Cuộc gọi cốt truyện bây giờ không vẽ dữ liệu gốc y2 nữa mà là phiên bản nhân bản yf (được giữ bên trong đối tượng trợ giúp được tính toán trước FudgeAxis ), chạy theo thang đo của y1 . Objet ggplot ban đầu sau đó được thao tác với chức năng trợ giúp của Kohske là PlotWithFudgeAxis để thêm trục thứ hai bảo toàn thang đo của y2 . Nó âm mưu cũng như âm mưu thao túng.

FudgeAxis <- CalcFudgeAxis( df$y1, df$y2 )

tmpPlot <- ggplot(data=df, aes(label=item)) +
      theme_bw() + 
      geom_segment(aes(x='G1', xend='G2', y=y1, yend=FudgeAxis$yf), color='grey')+
      geom_text(aes(x='G1', y=y1), color='blue') +
      geom_text(aes(x='G2', y=FudgeAxis$yf), color='red') +
      theme(legend.position='none', panel.grid=element_blank())

PlotWithFudgeAxis(tmpPlot, FudgeAxis)

Điều này bây giờ âm mưu như mong muốn với hai trục, y1 ở bên trái và y2 ở bên phải

2 trục

Giải pháp trên là, để nói thẳng, một vụ hack run rẩy hạn chế. Khi nó chơi với kernel ggplot, nó sẽ đưa ra một số cảnh báo rằng chúng ta trao đổi các thang đo sau thực tế, v.v. Nó phải được xử lý cẩn thận và có thể tạo ra một số hành vi không mong muốn trong một cài đặt khác. Cũng như người ta có thể cần phải xoay quanh các chức năng của trình trợ giúp để có được bố cục như mong muốn. Vị trí của chú giải là một vấn đề như vậy (nó sẽ được đặt giữa bảng điều khiển và trục mới; đây là lý do tại sao tôi bỏ nó). Việc chia tỷ lệ / căn chỉnh của trục 2 cũng hơi khó khăn: Mã ở trên hoạt động độc đáo khi cả hai thang đo đều có "0", một trục khác sẽ bị dịch chuyển. Vì vậy, chắc chắn với một số cơ hội để cải thiện ...

Trong trường hợp muốn lưu pic, người ta phải ngắt cuộc gọi vào thiết bị mở / đóng:

png(...)
PlotWithFudgeAxis(tmpPlot, FudgeAxis)
dev.off()

9

Bài viết sau đây đã giúp tôi kết hợp hai lô được tạo bởi ggplot2 trên một hàng:

Nhiều biểu đồ trên một trang (ggplot2) của Cookbook cho R

Và đây là những gì mã có thể trông giống như trong trường hợp này:

p1 <- 
  ggplot() + aes(mns)+ geom_histogram(aes(y=..density..), binwidth=0.01, colour="black", fill="white") + geom_vline(aes(xintercept=mean(mns, na.rm=T)), color="red", linetype="dashed", size=1) +  geom_density(alpha=.2)

p2 <- 
  ggplot() + aes(mns)+ geom_histogram( binwidth=0.01, colour="black", fill="white") + geom_vline(aes(xintercept=mean(mns, na.rm=T)), color="red", linetype="dashed", size=1)  

multiplot(p1,p2,cols=2)

Điều gì đã xảy ra với chức năng nhiều điểm? Tôi nhận được một lỗi mà chức năng không thể tìm thấy, mặc dù thực tế là tôi đã cài đặt và tải thư viện ggplot2.
Nneka

1
@Danka Hàm bội là một chức năng tùy chỉnh (ở cuối trang được liên kết).
Dribbel

Bạn có thể thêm cốt truyện?
Sibo Jiang

Gần đây, có nhiều gói có nhiều tùy chọn / tính năng hơn multiplot stackoverflow.com/a/51220506
Tung

7

Đối với tôi, phần khó khăn là tìm ra hàm biến đổi giữa hai trục. Tôi đã sử dụng myCurveFit cho điều đó.

> dput(combined_80_8192 %>% filter (time > 270, time < 280))
structure(list(run = c(268L, 268L, 268L, 268L, 268L, 268L, 268L, 
268L, 268L, 268L, 263L, 263L, 263L, 263L, 263L, 263L, 263L, 263L, 
263L, 263L, 269L, 269L, 269L, 269L, 269L, 269L, 269L, 269L, 269L, 
269L, 261L, 261L, 261L, 261L, 261L, 261L, 261L, 261L, 261L, 261L, 
267L, 267L, 267L, 267L, 267L, 267L, 267L, 267L, 267L, 267L, 265L, 
265L, 265L, 265L, 265L, 265L, 265L, 265L, 265L, 265L, 266L, 266L, 
266L, 266L, 266L, 266L, 266L, 266L, 266L, 266L, 262L, 262L, 262L, 
262L, 262L, 262L, 262L, 262L, 262L, 262L, 264L, 264L, 264L, 264L, 
264L, 264L, 264L, 264L, 264L, 264L, 260L, 260L, 260L, 260L, 260L, 
260L, 260L, 260L, 260L, 260L), repetition = c(8L, 8L, 8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
), module = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "scenario.node[0].nicVLCTail.phyVLC", class = "factor"), 
    configname = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L), .Label = "Road-Vlc", class = "factor"), packetByteLength = c(8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 
    8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L, 8192L
    ), numVehicles = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L
    ), dDistance = c(80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 
    80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 
    80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 
    80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 
    80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 
    80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 
    80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 
    80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L, 
    80L, 80L, 80L, 80L, 80L, 80L, 80L, 80L), time = c(270.166006903445, 
    271.173853699836, 272.175873251122, 273.177524313334, 274.182946177105, 
    275.188959464989, 276.189675339937, 277.198250244799, 278.204619457189, 
    279.212562800009, 270.164199199177, 271.168527215152, 272.173072994958, 
    273.179210429715, 274.184351047337, 275.18980754378, 276.194816792995, 
    277.198598277809, 278.202398083519, 279.210634593917, 270.210674322891, 
    271.212395107473, 272.218871923292, 273.219060500457, 274.220486359614, 
    275.22401452372, 276.229646658839, 277.231060448138, 278.240407241942, 
    279.2437126347, 270.283554249858, 271.293168593832, 272.298574288769, 
    273.304413221348, 274.306272082517, 275.309023049011, 276.317805897347, 
    277.324403550028, 278.332855848701, 279.334046374594, 270.118608539613, 
    271.127947700074, 272.133887145863, 273.135726000491, 274.135994529981, 
    275.136563912708, 276.140120735361, 277.144298344151, 278.146885137621, 
    279.147552358659, 270.206015567272, 271.214618077209, 272.216566814903, 
    273.225435592582, 274.234014573683, 275.242949179958, 276.248417809711, 
    277.248800670023, 278.249750333404, 279.252926560188, 270.217182684494, 
    271.218357511397, 272.224698488895, 273.231112784327, 274.238740508457, 
    275.242715184122, 276.249053562718, 277.250325509798, 278.258488063493, 
    279.261141590137, 270.282904173953, 271.284689544638, 272.294220723234, 
    273.299749415592, 274.30628880553, 275.312075103126, 276.31579134717, 
    277.321905523606, 278.326305136748, 279.333056502253, 270.258991527456, 
    271.260224091407, 272.270076810133, 273.27052037648, 274.274119348094, 
    275.280808254502, 276.286353887245, 277.287064312339, 278.294444793276, 
    279.296772014594, 270.333066283904, 271.33877455992, 272.345842319903, 
    273.350858180493, 274.353972278505, 275.360454510107, 276.365088896161, 
    277.369166956941, 278.372571708911, 279.38017503079), distanceToTx = c(80.255266401689, 
    80.156059067023, 79.98823695539, 79.826647129071, 79.76678667135, 
    79.788239825292, 79.734539327997, 79.74766421514, 79.801243848241, 
    79.765920888341, 80.255266401689, 80.15850240049, 79.98823695539, 
    79.826647129071, 79.76678667135, 79.788239825292, 79.735078924078, 
    79.74766421514, 79.801243848241, 79.764622734914, 80.251248121732, 
    80.146436869316, 79.984682320466, 79.82292012342, 79.761908518748, 
    79.796988776281, 79.736920997657, 79.745038376718, 79.802638836686, 
    79.770029970452, 80.243475525691, 80.127918207499, 79.978303140866, 
    79.816259117883, 79.749322030693, 79.809916018889, 79.744456560867, 
    79.738655068783, 79.788697533211, 79.784288359619, 80.260412958482, 
    80.168426829066, 79.992034911214, 79.830845773284, 79.7756751763, 
    79.778156038931, 79.732399593756, 79.752769548846, 79.799967731078, 
    79.757585110481, 80.251248121732, 80.146436869316, 79.984682320466, 
    79.822062073459, 79.75884601899, 79.801590491435, 79.738335109094, 
    79.74347007248, 79.803215965043, 79.771471198955, 80.250257298678, 
    80.146436869316, 79.983831684476, 79.822062073459, 79.75884601899, 
    79.801590491435, 79.738335109094, 79.74347007248, 79.803849157574, 
    79.771471198955, 80.243475525691, 80.130180105198, 79.978303140866, 
    79.816881283718, 79.749322030693, 79.80984572883, 79.744456560867, 
    79.738655068783, 79.790548644175, 79.784288359619, 80.246349000313, 
    80.137056554491, 79.980581246037, 79.818924707937, 79.753176142361, 
    79.808777040341, 79.741609845588, 79.740770913572, 79.796316397253, 
    79.777593733292, 80.238796415443, 80.119021911134, 79.974810568944, 
    79.814065350562, 79.743657315504, 79.810146783217, 79.749945098869, 
    79.737122584544, 79.781650522348, 79.791554933936), headerNoError = c(0.99999999989702, 
    0.9999999999981, 0.99999999999946, 0.9999999928026, 0.99999873265475, 
    0.77080141574964, 0.99007491438593, 0.99994396605059, 0.45588747062284, 
    0.93484381262491, 0.99999999989702, 0.99999999999816, 0.99999999999946, 
    0.9999999928026, 0.99999873265475, 0.77080141574964, 0.99008458785106, 
    0.99994396605059, 0.45588747062284, 0.93480223051707, 0.99999999989735, 
    0.99999999999789, 0.99999999999946, 0.99999999287551, 0.99999876302649, 
    0.46903147501117, 0.98835168988253, 0.99994427085086, 0.45235035271542, 
    0.93496741877335, 0.99999999989803, 0.99999999999781, 0.99999999999948, 
    0.99999999318224, 0.99994254156311, 0.46891362282273, 0.93382613917348, 
    0.99994594904099, 0.93002915596843, 0.93569767251247, 0.99999999989658, 
    0.99999999998074, 0.99999999999946, 0.99999999272802, 0.99999871586781, 
    0.76935240919896, 0.99002587758346, 0.99999881589732, 0.46179415706093, 
    0.93417422376389, 0.99999999989735, 0.99999999999789, 0.99999999999946, 
    0.99999999289347, 0.99999876940486, 0.46930769326427, 0.98837353639905, 
    0.99994447154714, 0.16313586712094, 0.93500824170148, 0.99999999989744, 
    0.99999999999789, 0.99999999999946, 0.99999999289347, 0.99999876940486, 
    0.46930769326427, 0.98837353639905, 0.99994447154714, 0.16330039178981, 
    0.93500824170148, 0.99999999989803, 0.99999999999781, 0.99999999999948, 
    0.99999999316541, 0.99994254156311, 0.46794586553266, 0.93382613917348, 
    0.99994594904099, 0.9303627789484, 0.93569767251247, 0.99999999989778, 
    0.9999999999978, 0.99999999999948, 0.99999999311433, 0.99999878195152, 
    0.47101897739483, 0.93368891853679, 0.99994556595217, 0.7571113417265, 
    0.93553999975802, 0.99999999998191, 0.99999999999784, 0.99999999999971, 
    0.99999891129658, 0.99994309267792, 0.46510628979591, 0.93442584181035, 
    0.99894450514543, 0.99890078483692, 0.76933812306423), receivedPower_dbm = c(-93.023492290586, 
    -92.388378035287, -92.205716340607, -93.816400586752, -95.023489422885, 
    -100.86308557253, -98.464763536915, -96.175707680373, -102.06189538385, 
    -99.716653422746, -93.023492290586, -92.384760627397, -92.205716340607, 
    -93.816400586752, -95.023489422885, -100.86308557253, -98.464201120719, 
    -96.175707680373, -102.06189538385, -99.717150021506, -93.022927803442, 
    -92.404017215549, -92.204561341714, -93.814319484729, -95.016990717792, 
    -102.01669022332, -98.558088145955, -96.173817001483, -102.07406915124, 
    -99.71517574876, -93.021813165972, -92.409586309743, -92.20229160243, 
    -93.805335867418, -96.184419849593, -102.01709540787, -99.728735187547, 
    -96.163233028048, -99.772547164798, -99.706399753853, -93.024204617071, 
    -92.745813384859, -92.206884754512, -93.818508150122, -95.027018807793, 
    -100.87000577258, -98.467607232407, -95.005311380324, -102.04157607608, 
    -99.724619517, -93.022927803442, -92.404017215549, -92.204561341714, 
    -93.813803344588, -95.015606885523, -102.0157405687, -98.556982278361, 
    -96.172566862738, -103.21871579865, -99.714687230796, -93.022787428238, 
    -92.404017215549, -92.204274688493, -93.813803344588, -95.015606885523, 
    -102.0157405687, -98.556982278361, -96.172566862738, -103.21784988098, 
    -99.714687230796, -93.021813165972, -92.409950613665, -92.20229160243, 
    -93.805838770576, -96.184419849593, -102.02042267497, -99.728735187547, 
    -96.163233028048, -99.768774335378, -99.706399753853, -93.022228914406, 
    -92.411048503835, -92.203136463155, -93.807357409082, -95.012865008237, 
    -102.00985717796, -99.730352912911, -96.165675535906, -100.92744056572, 
    -99.708301333236, -92.735781110993, -92.408137395049, -92.119533319039, 
    -94.982938427575, -96.181073124017, -102.03018610927, -99.721633629806, 
    -97.32940323644, -97.347613268692, -100.87007386786), snr = c(49.848348091678, 
    57.698190927109, 60.17669971462, 41.529809724535, 31.452202106925, 
    8.1976890851341, 14.240447804094, 24.122884195464, 6.2202875499406, 
    10.674183333671, 49.848348091678, 57.746270018264, 60.17669971462, 
    41.529809724535, 31.452202106925, 8.1976890851341, 14.242292077376, 
    24.122884195464, 6.2202875499406, 10.672962852322, 49.854827699773, 
    57.49079026127, 60.192705735317, 41.549715223147, 31.499301851462, 
    6.2853718719014, 13.937702343688, 24.133388256416, 6.2028757927148, 
    10.677815810561, 49.867624820879, 57.417115267867, 60.224172277442, 
    41.635752021705, 24.074540962859, 6.2847854917092, 10.644529778044, 
    24.19227425387, 10.537686730745, 10.699414795917, 49.84017267426, 
    53.139646558768, 60.160512118809, 41.509660845114, 31.42665220053, 
    8.1846370024428, 14.231126423354, 31.584125885363, 6.2494585568733, 
    10.654622041348, 49.854827699773, 57.49079026127, 60.192705735317, 
    41.55465351989, 31.509340361646, 6.2867464196657, 13.941251828322, 
    24.140336174865, 4.765718874642, 10.679016976694, 49.856439162736, 
    57.49079026127, 60.196678846453, 41.55465351989, 31.509340361646, 
    6.2867464196657, 13.941251828322, 24.140336174865, 4.7666691818074, 
    10.679016976694, 49.867624820879, 57.412299088098, 60.224172277442, 
    41.630930975211, 24.074540962859, 6.279972363168, 10.644529778044, 
    24.19227425387, 10.546845071479, 10.699414795917, 49.862851240855, 
    57.397787176282, 60.212457625018, 41.61637603957, 31.529239767749, 
    6.2952688513108, 10.640565481982, 24.178672145334, 8.0771089950663, 
    10.694731030907, 53.262541905639, 57.43627424514, 61.382796189332, 
    31.747253311549, 24.093100244121, 6.2658701281075, 10.661949889074, 
    18.495227442305, 18.417839037171, 8.1845086722809), frameId = c(15051, 
    15106, 15165, 15220, 15279, 15330, 15385, 15452, 15511, 15566, 
    15019, 15074, 15129, 15184, 15239, 15298, 15353, 15412, 15471, 
    15526, 14947, 14994, 15057, 15112, 15171, 15226, 15281, 15332, 
    15391, 15442, 14971, 15030, 15085, 15144, 15203, 15262, 15321, 
    15380, 15435, 15490, 14915, 14978, 15033, 15092, 15147, 15198, 
    15257, 15312, 15371, 15430, 14975, 15034, 15089, 15140, 15195, 
    15254, 15313, 15368, 15427, 15478, 14987, 15046, 15105, 15160, 
    15215, 15274, 15329, 15384, 15447, 15506, 14943, 15002, 15061, 
    15116, 15171, 15230, 15285, 15344, 15399, 15454, 14971, 15026, 
    15081, 15136, 15195, 15258, 15313, 15368, 15423, 15478, 15039, 
    15094, 15149, 15204, 15263, 15314, 15369, 15428, 15487, 15546
    ), packetOkSinr = c(0.99999999314881, 0.9999999998736, 0.99999999996428, 
    0.99999952114066, 0.99991568416005, 3.00628034688444e-08, 
    0.51497487795954, 0.99627877136019, 0, 0.011303253101957, 
    0.99999999314881, 0.99999999987726, 0.99999999996428, 0.99999952114066, 
    0.99991568416005, 3.00628034688444e-08, 0.51530974419663, 
    0.99627877136019, 0, 0.011269851265775, 0.9999999931708, 
    0.99999999985986, 0.99999999996428, 0.99999952599145, 0.99991770469509, 
    0, 0.45861812482641, 0.99629897628155, 0, 0.011403119534097, 
    0.99999999321568, 0.99999999985437, 0.99999999996519, 0.99999954639936, 
    0.99618434878558, 0, 0.010513119213425, 0.99641022914441, 
    0.00801687746446111, 0.012011103529927, 0.9999999931195, 
    0.99999999871861, 0.99999999996428, 0.99999951617905, 0.99991456738049, 
    2.6525298291169e-08, 0.51328066587104, 0.9999212220316, 0, 
    0.010777054258914, 0.9999999931708, 0.99999999985986, 0.99999999996428, 
    0.99999952718674, 0.99991812902805, 0, 0.45929307038653, 
    0.99631228046814, 0, 0.011436292559188, 0.99999999317629, 
    0.99999999985986, 0.99999999996428, 0.99999952718674, 0.99991812902805, 
    0, 0.45929307038653, 0.99631228046814, 0, 0.011436292559188, 
    0.99999999321568, 0.99999999985437, 0.99999999996519, 0.99999954527918, 
    0.99618434878558, 0, 0.010513119213425, 0.99641022914441, 
    0.00821047996950475, 0.012011103529927, 0.99999999319919, 
    0.99999999985345, 0.99999999996519, 0.99999954188106, 0.99991896371849, 
    0, 0.010410830482692, 0.996384831822, 9.12484388049251e-09, 
    0.011877185067536, 0.99999999879646, 0.9999999998562, 0.99999999998077, 
    0.99992756868677, 0.9962208785486, 0, 0.010971897073662, 
    0.93214999078663, 0.92943956665979, 2.64925478221656e-08), 
    snir = c(49.848348091678, 57.698190927109, 60.17669971462, 
    41.529809724535, 31.452202106925, 8.1976890851341, 14.240447804094, 
    24.122884195464, 6.2202875499406, 10.674183333671, 49.848348091678, 
    57.746270018264, 60.17669971462, 41.529809724535, 31.452202106925, 
    8.1976890851341, 14.242292077376, 24.122884195464, 6.2202875499406, 
    10.672962852322, 49.854827699773, 57.49079026127, 60.192705735317, 
    41.549715223147, 31.499301851462, 6.2853718719014, 13.937702343688, 
    24.133388256416, 6.2028757927148, 10.677815810561, 49.867624820879, 
    57.417115267867, 60.224172277442, 41.635752021705, 24.074540962859, 
    6.2847854917092, 10.644529778044, 24.19227425387, 10.537686730745, 
    10.699414795917, 49.84017267426, 53.139646558768, 60.160512118809, 
    41.509660845114, 31.42665220053, 8.1846370024428, 14.231126423354, 
    31.584125885363, 6.2494585568733, 10.654622041348, 49.854827699773, 
    57.49079026127, 60.192705735317, 41.55465351989, 31.509340361646, 
    6.2867464196657, 13.941251828322, 24.140336174865, 4.765718874642, 
    10.679016976694, 49.856439162736, 57.49079026127, 60.196678846453, 
    41.55465351989, 31.509340361646, 6.2867464196657, 13.941251828322, 
    24.140336174865, 4.7666691818074, 10.679016976694, 49.867624820879, 
    57.412299088098, 60.224172277442, 41.630930975211, 24.074540962859, 
    6.279972363168, 10.644529778044, 24.19227425387, 10.546845071479, 
    10.699414795917, 49.862851240855, 57.397787176282, 60.212457625018, 
    41.61637603957, 31.529239767749, 6.2952688513108, 10.640565481982, 
    24.178672145334, 8.0771089950663, 10.694731030907, 53.262541905639, 
    57.43627424514, 61.382796189332, 31.747253311549, 24.093100244121, 
    6.2658701281075, 10.661949889074, 18.495227442305, 18.417839037171, 
    8.1845086722809), ookSnirBer = c(8.8808636558081e-24, 3.2219795637026e-27, 
    2.6468895519653e-28, 3.9807779074715e-20, 1.0849324265615e-15, 
    2.5705217057696e-05, 4.7313805615763e-08, 1.8800438086075e-12, 
    0.00021005320203921, 1.9147343768384e-06, 8.8808636558081e-24, 
    3.0694773489537e-27, 2.6468895519653e-28, 3.9807779074715e-20, 
    1.0849324265615e-15, 2.5705217057696e-05, 4.7223753038869e-08, 
    1.8800438086075e-12, 0.00021005320203921, 1.9171738578051e-06, 
    8.8229427230445e-24, 3.9715925056443e-27, 2.6045198111088e-28, 
    3.9014083702734e-20, 1.0342658440386e-15, 0.00019591630514278, 
    6.4692014108683e-08, 1.8600094209271e-12, 0.0002140067535655, 
    1.9074922485477e-06, 8.7096574467175e-24, 4.2779443633862e-27, 
    2.5231916788231e-28, 3.5761615214425e-20, 1.9750692814982e-12, 
    0.0001960392878411, 1.9748966344895e-06, 1.7515881895994e-12, 
    2.2078334799411e-06, 1.8649940680806e-06, 8.954486301678e-24, 
    3.2021085732779e-25, 2.690441113724e-28, 4.0627628846548e-20, 
    1.1134484878561e-15, 2.6061691733331e-05, 4.777159157954e-08, 
    9.4891388749738e-16, 0.00020359398491544, 1.9542110660398e-06, 
    8.8229427230445e-24, 3.9715925056443e-27, 2.6045198111088e-28, 
    3.8819641115984e-20, 1.0237769828158e-15, 0.00019562832342849, 
    6.4455095380046e-08, 1.8468752030971e-12, 0.0010099091367628, 
    1.9051035165106e-06, 8.8085966897635e-24, 3.9715925056443e-27, 
    2.594108048185e-28, 3.8819641115984e-20, 1.0237769828158e-15, 
    0.00019562832342849, 6.4455095380046e-08, 1.8468752030971e-12, 
    0.0010088638355194, 1.9051035165106e-06, 8.7096574467175e-24, 
    4.2987746909572e-27, 2.5231916788231e-28, 3.593647329558e-20, 
    1.9750692814982e-12, 0.00019705170257492, 1.9748966344895e-06, 
    1.7515881895994e-12, 2.1868296425817e-06, 1.8649940680806e-06, 
    8.7517439682173e-24, 4.3621551072316e-27, 2.553168170837e-28, 
    3.6469582463164e-20, 1.0032983660212e-15, 0.00019385229409318, 
    1.9830820164805e-06, 1.7760568361323e-12, 2.919419915209e-05, 
    1.8741284335866e-06, 2.8285944348148e-25, 4.1960751547207e-27, 
    7.8468215407139e-29, 8.0407329049747e-16, 1.9380328071065e-12, 
    0.00020004849911333, 1.9393279417733e-06, 5.9354475879597e-10, 
    6.4258355913627e-10, 2.6065221215415e-05), ookSnrBer = c(8.8808636558081e-24, 
    3.2219795637026e-27, 2.6468895519653e-28, 3.9807779074715e-20, 
    1.0849324265615e-15, 2.5705217057696e-05, 4.7313805615763e-08, 
    1.8800438086075e-12, 0.00021005320203921, 1.9147343768384e-06, 
    8.8808636558081e-24, 3.0694773489537e-27, 2.6468895519653e-28, 
    3.9807779074715e-20, 1.0849324265615e-15, 2.5705217057696e-05, 
    4.7223753038869e-08, 1.8800438086075e-12, 0.00021005320203921, 
    1.9171738578051e-06, 8.8229427230445e-24, 3.9715925056443e-27, 
    2.6045198111088e-28, 3.9014083702734e-20, 1.0342658440386e-15, 
    0.00019591630514278, 6.4692014108683e-08, 1.8600094209271e-12, 
    0.0002140067535655, 1.9074922485477e-06, 8.7096574467175e-24, 
    4.2779443633862e-27, 2.5231916788231e-28, 3.5761615214425e-20, 
    1.9750692814982e-12, 0.0001960392878411, 1.9748966344895e-06, 
    1.7515881895994e-12, 2.2078334799411e-06, 1.8649940680806e-06, 
    8.954486301678e-24, 3.2021085732779e-25, 2.690441113724e-28, 
    4.0627628846548e-20, 1.1134484878561e-15, 2.6061691733331e-05, 
    4.777159157954e-08, 9.4891388749738e-16, 0.00020359398491544, 
    1.9542110660398e-06, 8.8229427230445e-24, 3.9715925056443e-27, 
    2.6045198111088e-28, 3.8819641115984e-20, 1.0237769828158e-15, 
    0.00019562832342849, 6.4455095380046e-08, 1.8468752030971e-12, 
    0.0010099091367628, 1.9051035165106e-06, 8.8085966897635e-24, 
    3.9715925056443e-27, 2.594108048185e-28, 3.8819641115984e-20, 
    1.0237769828158e-15, 0.00019562832342849, 6.4455095380046e-08, 
    1.8468752030971e-12, 0.0010088638355194, 1.9051035165106e-06, 
    8.7096574467175e-24, 4.2987746909572e-27, 2.5231916788231e-28, 
    3.593647329558e-20, 1.9750692814982e-12, 0.00019705170257492, 
    1.9748966344895e-06, 1.7515881895994e-12, 2.1868296425817e-06, 
    1.8649940680806e-06, 8.7517439682173e-24, 4.3621551072316e-27, 
    2.553168170837e-28, 3.6469582463164e-20, 1.0032983660212e-15, 
    0.00019385229409318, 1.9830820164805e-06, 1.7760568361323e-12, 
    2.919419915209e-05, 1.8741284335866e-06, 2.8285944348148e-25, 
    4.1960751547207e-27, 7.8468215407139e-29, 8.0407329049747e-16, 
    1.9380328071065e-12, 0.00020004849911333, 1.9393279417733e-06, 
    5.9354475879597e-10, 6.4258355913627e-10, 2.6065221215415e-05
    )), class = "data.frame", row.names = c(NA, -100L), .Names = c("run", 
"repetition", "module", "configname", "packetByteLength", "numVehicles", 
"dDistance", "time", "distanceToTx", "headerNoError", "receivedPower_dbm", 
"snr", "frameId", "packetOkSinr", "snir", "ookSnirBer", "ookSnrBer"
))

Tìm hàm biến đổi

  1. y1 -> y2 Hàm này được sử dụng để chuyển đổi dữ liệu của trục y thứ cấp được "chuẩn hóa" theo trục y đầu tiên

nhập mô tả hình ảnh ở đây

hàm biến đổi: f(y1) = 0.025*x + 2.75


  1. y2 -> y1 Hàm này được sử dụng để biến đổi các điểm ngắt của trục y thứ nhất thành các giá trị của trục y thứ hai. Lưu ý rằng trục được hoán đổi ngay bây giờ.

nhập mô tả hình ảnh ở đây

hàm biến đổi: f(y1) = 40*x - 110


Âm mưu

Lưu ý cách các hàm chuyển đổi được sử dụng trong lệnh ggplotgọi để chuyển đổi dữ liệu "đang hoạt động"

ggplot(data=combined_80_8192 %>% filter (time > 270, time < 280), aes(x=time) ) +
  stat_summary(aes(y=receivedPower_dbm ), fun.y=mean, geom="line", colour="black") +
  stat_summary(aes(y=packetOkSinr*40 - 110 ), fun.y=mean, geom="line", colour="black", position = position_dodge(width=10)) +
  scale_x_continuous() +
  scale_y_continuous(breaks = seq(-0,-110,-10), "y_first", sec.axis=sec_axis(~.*0.025+2.75, name="y_second") ) 

Cuộc stat_summarygọi đầu tiên là cuộc gọi đặt cơ sở cho trục y đầu tiên. Cuộc stat_summarygọi thứ hai được gọi để chuyển đổi dữ liệu. Hãy nhớ rằng tất cả các dữ liệu sẽ lấy làm cơ sở cho trục y đầu tiên. Vì vậy, dữ liệu cần phải được chuẩn hóa cho trục y đầu tiên. Để làm điều đó tôi sử dụng hàm chuyển đổi trên dữ liệu:y=packetOkSinr*40 - 110

Bây giờ để chuyển đổi trục thứ hai, tôi sử dụng chức năng ngược lại trong scale_y_continuouscuộc gọi : sec.axis=sec_axis(~.*0.025+2.75, name="y_second").

nhập mô tả hình ảnh ở đây


2
R có thể làm điều này, coef(lm(c(-70, -110) ~ c(1,0)))coef(lm(c(1,0) ~ c(-70, -110))). Bạn có thể xác định chức năng của người trợ giúp, chẳng hạn như equationise <- function(range = c(-70, -110), target = c(1,0)){ c = coef(lm(target ~ range)) as.formula(substitute(~ a*. + b, list(a=c[[2]], b=c[[1]]))) }
baptiste

yeap, tôi biết ... chỉ nghĩ rằng trang web sẽ trực quan hơn
user4786271

4

Chúng tôi chắc chắn có thể xây dựng một cốt truyện với kép Y-axises sử dụng cơ sở R Chức năng plot.

# pseudo dataset
df <- data.frame(x = seq(1, 1000, 1), y1 = sample.int(100, 1000, replace=T), y2 = sample(50, 1000, replace = T))

# plot first plot 
with(df, plot(y1 ~ x, col = "red"))

# set new plot
par(new = T) 

# plot second plot, but without axis
with(df, plot(y2 ~ x, type = "l", xaxt = "n", yaxt = "n", xlab = "", ylab = ""))

# define y-axis and put y-labs
axis(4)
with(df, mtext("y2", side = 4))

1

Bạn có thể sử dụng facet_wrap(~ variable, ncol= )trên một biến để tạo một so sánh mới. Nó không nằm trên cùng một trục, nhưng nó tương tự nhau.


1

Tôi thừa nhận và đồng ý với hadley (và những người khác), rằng các thang đo y riêng biệt là "thiếu sót cơ bản". Phải nói rằng - tôi thường muốn ggplot2có tính năng này - đặc biệt, khi dữ liệu ở định dạng rộng và tôi nhanh chóng muốn trực quan hóa hoặc kiểm tra dữ liệu (nghĩa là chỉ sử dụng cá nhân).

Mặc dù tidyversethư viện giúp dễ dàng chuyển đổi dữ liệu sang định dạng dài (như vậy facet_grid()sẽ hoạt động), quá trình này vẫn không tầm thường, như được thấy dưới đây:

library(tidyverse)
df.wide %>%
    # Select only the columns you need for the plot.
    select(date, column1, column2, column3) %>%
    # Create an id column – needed in the `gather()` function.
    mutate(id = n()) %>%
    # The `gather()` function converts to long-format. 
    # In which the `type` column will contain three factors (column1, column2, column3),
    # and the `value` column will contain the respective values.
    # All the while we retain the `id` and `date` columns.
    gather(type, value, -id, -date) %>%
    # Create the plot according to your specifications
    ggplot(aes(x = date, y = value)) +
        geom_line() +
        # Create a panel for each `type` (ie. column1, column2, column3).
        # If the types have different scales, you can use the `scales="free"` option.
        facet_grid(type~., scales = "free")

Tại thời điểm viết ggplot2 đã hỗ trợ điều này thông qua sec_axis.
Konrad Rudolph

0

Câu trả lời của Hadley đưa ra một tài liệu tham khảo thú vị cho báo cáo Rìu hai trục của Stephen Few trong đồ thị Chúng có phải là giải pháp tốt nhất? .

Tôi không biết OP nghĩa là gì với "số đếm" và "tỷ lệ" nhưng một tìm kiếm nhanh mang lại cho tôi Số lượng và Tỷ lệ , vì vậy tôi nhận được một số dữ liệu về Tai nạn trong Leo núi Bắc Mỹ 1 :

Years<-c("1998","1999","2000","2001","2002","2003","2004")
Persons.Involved<-c(281,248,301,276,295,231,311)
Fatalities<-c(20,17,24,16,34,18,35)
rate=100*Fatalities/Persons.Involved
df<-data.frame(Years=Years,Persons.Involved=Persons.Involved,Fatalities=Fatalities,rate=rate)
print(df,row.names = FALSE)

 Years Persons.Involved Fatalities      rate
  1998              281         20  7.117438
  1999              248         17  6.854839
  2000              301         24  7.973422
  2001              276         16  5.797101
  2002              295         34 11.525424
  2003              231         18  7.792208
  2004              311         35 11.254019

Và sau đó tôi đã cố gắng thực hiện biểu đồ như Vài đề xuất ở trang 7 của báo cáo đã nói ở trên (và làm theo yêu cầu của OP để vẽ biểu đồ đếm dưới dạng biểu đồ thanh và tỷ lệ dưới dạng biểu đồ đường):

Một giải pháp ít rõ ràng hơn, chỉ hoạt động trong chuỗi thời gian, là chuyển đổi tất cả các bộ giá trị thành thang đo định lượng chung bằng cách hiển thị chênh lệch tỷ lệ phần trăm giữa mỗi giá trị và giá trị tham chiếu (hoặc chỉ mục). Chẳng hạn, chọn một thời điểm cụ thể, chẳng hạn như khoảng đầu tiên xuất hiện trong biểu đồ và biểu thị từng giá trị tiếp theo dưới dạng chênh lệch tỷ lệ phần trăm giữa nó và giá trị ban đầu. Điều này được thực hiện bằng cách chia giá trị tại từng thời điểm cho giá trị cho thời điểm ban đầu và sau đó nhân nó với 100 để chuyển đổi tỷ lệ thành tỷ lệ phần trăm, như minh họa dưới đây.

df2<-df
df2$Persons.Involved <- 100*df$Persons.Involved/df$Persons.Involved[1]
df2$rate <- 100*df$rate/df$rate[1]
plot(ggplot(df2)+
  geom_bar(aes(x=Years,weight=Persons.Involved))+
  geom_line(aes(x=Years,y=rate,group=1))+
  theme(text = element_text(size=30))
  )

Và đây là kết quả: nhập mô tả hình ảnh ở đây

Nhưng tôi không thích nó nhiều và tôi không thể dễ dàng đặt một huyền thoại về nó ...

1 WILLIAMON, Jed, et al. Tai nạn trong leo núi Bắc Mỹ 2005. Sách leo núi, 2005.


0

Nó dường như là một câu hỏi đơn giản nhưng nó xoay quanh 2 câu hỏi cơ bản. A) Cách xử lý dữ liệu đa hướng trong khi trình bày trong biểu đồ so sánh và thứ hai, B) liệu điều này có thể được thực hiện mà không cần một số thực hành quy tắc ngón tay cái của lập trình R như i) làm tan chảy dữ liệu, ii) thêm vào, iii) thêm lớp khác đến lớp hiện có. Giải pháp được đưa ra dưới đây thỏa mãn cả hai điều kiện trên vì nó xử lý dữ liệu mà không phải hủy bỏ nó và thứ hai, các kỹ thuật được đề cập không được sử dụng.

Đây là kết quả, tốt hơn và cải thiện

Đối với những người quan tâm muốn biết thêm về phương pháp này, xin vui lòng theo liên kết dưới đây. Cách vẽ biểu đồ trục 2- y với các thanh cạnh nhau mà không thu nhỏ lại dữ liệu


0

Tôi thấy câu trả lời này đã giúp tôi nhiều nhất, nhưng thấy rằng có một số trường hợp cạnh mà nó dường như không xử lý chính xác, đặc biệt là các trường hợp tiêu cực và cũng là trường hợp giới hạn của tôi có khoảng cách 0 (có thể xảy ra nếu chúng tôi đang nắm lấy giới hạn của chúng tôi từ tối đa / phút của dữ liệu). Thử nghiệm dường như chỉ ra rằng điều này hoạt động nhất quán

Tôi sử dụng mã sau đây. Ở đây tôi giả sử chúng ta có [x1, x2] mà chúng ta muốn chuyển đổi thành [y1, y2]. Cách tôi xử lý việc này là biến đổi [x1, x2] thành [0,1] (một biến đổi đủ đơn giản), sau đó [0,1] thành [y1, y2].

climate <- tibble(
  Month = 1:12,
  Temp = c(-4,-4,0,5,11,15,16,15,11,6,1,-3),
  Precip = c(49,36,47,41,53,65,81,89,90,84,73,55)
)
#Set the limits of each axis manually:

  ylim.prim <- c(0, 180)   # in this example, precipitation
ylim.sec <- c(-4, 18)    # in this example, temperature



  b <- diff(ylim.sec)/diff(ylim.prim)

#If all values are the same this messes up the transformation, so we need to modify it here
if(b==0){
  ylim.sec <- c(ylim.sec[1]-1, ylim.sec[2]+1)
  b <- diff(ylim.sec)/diff(ylim.prim)
}
if (is.na(b)){
  ylim.prim <- c(ylim.prim[1]-1, ylim.prim[2]+1)
  b <- diff(ylim.sec)/diff(ylim.prim)
}


ggplot(climate, aes(Month, Precip)) +
  geom_col() +
  geom_line(aes(y = ylim.prim[1]+(Temp-ylim.sec[1])/b), color = "red") +
  scale_y_continuous("Precipitation", sec.axis = sec_axis(~((.-ylim.prim[1]) *b  + ylim.sec[1]), name = "Temperature"), limits = ylim.prim) +
  scale_x_continuous("Month", breaks = 1:12) +
  ggtitle("Climatogram for Oslo (1961-1990)")  

Các phần chính ở đây là chúng ta biến đổi trục y thứ cấp ~((.-ylim.prim[1]) *b + ylim.sec[1])và sau đó áp dụng nghịch đảo với các giá trị thực tế y = ylim.prim[1]+(Temp-ylim.sec[1])/b). Chúng ta cũng nên đảm bảo rằng limits = ylim.prim.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.