각 측면에 2 개의 y 축과 다른 스케일이있는 ggplot


231

카운트를 보여주는 막대 차트와 하나의 차트에 비율을 모두 나타내는 꺾은 선형 차트를 그려야합니다. 두 가지를 모두 따로 할 수 있지만, 함께 묶으면 첫 번째 레이어의 스케일 (예 geom_bar:)이 두 번째 레이어 와 겹칩니다 층 (즉 geom_line).

축을 geom_line오른쪽으로 움직일 수 있습니까 ?


5
rpubs.com/kohske/dual_axis_in_ggplot2 에서 접근 방식을 사용할 수 있습니까?
Tom Wenseleers 12


2
아래로 스크롤하여 현재 호출 되는 기본 ggplot2구현 을 볼 수 있습니다. scale_y_*sec.axis
PatrickT

답변:


106

때때로 고객은 두 개의 y 스케일을 원합니다. 그들에게 "결함이있는"연설을하는 것은 종종 무의미합니다. 그러나 ggplot2가 올바른 방식으로 일한다는 주장을 좋아합니다. ggplot이 실제로 일반 사용자에게 적절한 시각화 기술에 대해 교육하고 있다고 확신합니다.

어쩌면 패싯을 사용하여 두 데이터 시리즈를 자유롭게 비교할 수 있습니까? -예를 들어 여기 : https://github.com/hadley/ggplot2/wiki/Align-two-plots-on-a-page


30
나는 Andreas와 동의한다-때로는 (현재와 같은) 클라이언트는 같은 음모에 두 개의 데이터 세트를 원하고 Plotting Theory에 대해 말하는 것을 듣고 싶지 않다. 나는 그들에게 더 이상 원하지 않겠다고 설득해야한다. (항상 내가 싸우고 싶은 전투는 아니다) "내가 사용하는 플로팅 패키지가 그것을 지원하지 않는다" 그래서 나는이 특정 프로젝트를 위해 ggplot에서 오늘 전환하고 있습니다. = (
Ken Williams

58
플로팅 패키지가 작동 방식에 개인 의견을 삽입해야하는 이유는 무엇입니까? 아니요 괜찮습니다.
colin

5
링크가 썩어졌습니다. 답변을 수정하고 그 내용에 대한 요약을 게시 할 수 있습니까?
Zach

24
이 의견에 동의 할 수 없습니다 (rerant). 메시지를 신속하게 전달하기 위해 과학 저널 등의 엄격한 제한 등을 포함하여 정보를 가능한 한 많이 수집하는 것이 매우 일반적입니다! 따라서 두 번째 y 축을 추가하는 것이 어쨌든 ggplot은 내 의견으로는 도움이되어야합니다.
Stingery

57
의심의 여지없이 "결함이있는"및 "올바른 길"과 같은 단어가 실제로 실제로 의견이 많고 독단적 인 이론에 기반을 둔 것이 아니라 너무 많은 사람들이 생각할 수있는 이론을 기반으로하는 것처럼 놀랍니다. 이 완전히 도움이되지 않는 답변 (링크 뼈를 던짐)은 글을 쓸 때 72 개의 공감대가 있습니다. WHE 비교 시계열을 차이의 상관 관계를 발견하기가 훨씬 쉽기 때문에, 예를 들어, 동일한 차트에서 모두를 가지고 헤아릴 수 없을 수 있습니다. 매일 매일이 일을하는 고도로 교육을받은 수천 명의 금융 전문가에게 물어보십시오.
토마스 브라운

149

별도의 y 스케일이있는 플롯 (서로 변환되는 y 스케일이 아님)이 근본적으로 결함이 있다고 생각하기 때문에 ggplot2에서는 불가능합니다. 몇 가지 문제:

  • 는 되돌릴 수 없습니다. 플롯 공간의 점이 주어지면 데이터 공간의 점에 고유하게 다시 매핑 할 수 없습니다.

  • 다른 옵션과 비교하여 올바르게 읽기가 상대적으로 어렵습니다. 자세한 내용 은 Petra Isenberg, Anastasia Bezerianos, Pierre Dragicevic 및 Jean-Daniel Fekete의 이중 규모 데이터 차트에 대한 연구를 참조 하십시오.

  • 그것들은 쉽게 오도하기 위해 조작됩니다 : 축의 상대 스케일을 지정하는 독특한 방법은 없으므로 조작에 개방되어 있습니다. 정크 차트 블로그의 두 가지 예 : 하나 ,

  • 그들은 임의적입니다 : 왜 3, 4 또는 10이 아닌 2 개의 스케일 만 있습니까?

또한 그래프에서 이중 스케일 축이 최고의 솔루션 이라는 주제에 대한 Stephen Few의 긴 토론을 읽어보십시오 . .


39
당신의 의견을 설명해 주시겠습니까? 깨달음이 아니라, 나는 두 개의 독립 변수를 그리는 다소 간결한 방법이라고 생각합니다. 그것은 또한 요구되는 것처럼 보이는 기능이며 널리 사용됩니다.
KarlP

66
@hadley : 대부분 동의하지만, 여러 y 스케일에 대해 진정한 사용이 있습니다. 온도 데이터에 섭씨 및 화씨 스케일과 같은 동일한 데이터에 대해 서로 다른 2 개의 단위를 사용합니다.
Richie Cotton

11
@Hadley 귀하의 의견입니다. 내 과학자도 아니고 다른 많은 과학자도 아닙니다. 확실히 이것은 완전히 투명한 배경을 가진 두 번째 줄거리를 첫 번째 줄 바로 위에 놓아서 달성 할 수 있습니다. 경계 boxex의 모서리가 서로 정렬 / 등록되도록하는 방법을 모르겠습니다.
니콜라스 해밀턴

8
@hadley 예를 들어 Walther-Lieth Climate Diagrams 에서 두 개의 y 축이 일반적으로 사용됩니다. 가능한 혼란을 최소화하는 방법을
정하는

32
@hadley 죄송합니다. 주어진 기후 도표에 문제가있는 것은 없습니다. 온도와 강수량을 하나의 다이어그램 (고정 된 처방전으로)에 넣으면 습하거나 건조한 기후인지 먼저 먼저 추측 할 수 있습니다. 아니면 주위의 방법 : 온도, 강수량 및 "관계"를 시각화하는 더 좋은 방법은 무엇입니까? 어쨌든 ggplot2에서 작업 해 주셔서 감사합니다!
sebschub

121

ggplot2 2.2.0부터 다음과 같은 보조 축을 추가 할 수 있습니다 ( 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)")
  )

여기에 이미지 설명을 입력하십시오


25
단점은 예를 들어 새로운 변수가 아닌 현재 축의 일부 수식 변환 만 사용할 수 있다는 것입니다.
discipulus

41

위의 답변과 미세 조정 (그리고 가치있는 것)을 취하면 sec_axis다음을 통해 두 가지 척도를 달성 할 수 있습니다 .

단순하고 순수한 가상의 데이터 세트를 가정합니다 dt. 5 일 동안 중단 횟수와 생산성을 추적합니다.

        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

(두 열의 범위는 약 요소 5만큼 다릅니다).

다음 코드는 전체 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"))

결과는 다음과 같습니다 (코드 위 + 일부 색상 조정).

하나의 ggplot2에 두 개의 비늘

요점 ( sec_axisy_scale을 지정할 때 사용 하는 것 외에는 시리즈를 지정할 때 두 번째 데이터 계열에 각 값에 5 를 곱하는 것 입니다. sec_axis 정의에서 레이블을 올바르게 얻으려면 5로 나누고 형식화해야합니다. 위 코드에서 중요한 부분은 실제로 *5geom_line과 ~./5sec_axis (현재 값 .을 5로 나누는 공식 )에 있습니다.

이에 비해 (여기에서 접근 방식을 판단하고 싶지는 않습니다.) 이것은 서로 위에있는 두 개의 차트가 어떻게 보이는지입니다.

서로 위에있는 두 개의 차트

어느 쪽이 메시지를 더 잘 전달하는지 스스로 판단 할 수 있습니다 (“직장 사람들을 방해하지 마십시오!”). 그것이 공정한 결정 방법이라고 생각합니다.

두 이미지의 전체 코드가 (더 이상 단지 완전하고 실행할 준비가 무엇보다 정말 아니다) 여기에 있습니다 : https://gist.github.com/sebastianrothbucher/de847063f32fdff02c83b75f59c36a7d 여기에 대한 자세한 설명 : https : // sebastianrothbucher입니다. github.io/datascience/r/visualization/ggplot/2018/03/24/two-scales-ggplot-r.html


31

예를 들어, climatograph 와 같은 일반적인 사용 사례가 있습니다. 월별 온도와 강수량을 보여주는 . 다음은 변수의 하한을 0이 아닌 다른 값으로 설정할 수있게함으로써 Megatron의 솔루션에서 일반화 된 간단한 솔루션입니다.

데이터 예 :

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)
  )

다음 두 값을 데이터 한계에 가까운 값으로 설정하십시오 (그래프를 사용하여 그래프의 위치를 ​​조정할 수 있습니다. 축은 여전히 ​​정확합니다).

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

다음은 이러한 한계를 기반으로 필요한 계산을 수행하고 플롯 자체를 만듭니다.

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

빨간색 선이 오른쪽 y 축에 해당하는지 확인 theme하려면 코드에 문장을 추가 할 수 있습니다 .

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)")

오른쪽 축의 색상은 다음과 같습니다.

오른쪽 축이 붉은 색인 크리 마토 그램


이것은 ylim.prim및의 일부 값에서 나옵니다 ylim.sec.
Eric Krantz

5
대단하다. 2 축 차트가 "결함"이 아닌 좋은 예입니다. 그들이 생각하는 것보다 그들이 당신의 일에 대해 더 많이 알고 있다고 생각하는 일반적인 깔끔한 사고의 일부.
Leo Barlach

특정 축 제한 (내 경우에는 ylim.prim <-c (90, 130) 및 ylim.sec <-c (15, 30))을 선택하면 적용되지 않지만 임의의 제한을 선택하여 모든 스케일을 엉망으로 만듭니다. . 위 코드를 복사하고 변수 이름과 축 제한을 변경했을 때 누락 된 부분이 확실하지 않습니다.
Anke

@anke : ylim.prim 및 ylim.sec를 참조 할 때 텍스트가 약간 조잡합니다. 축의 한계를 나타내는 것이 아니라 데이터의 한계를 나타냅니다. 언급 한대로 ylim.prim <-c (90, 130) 및 ylim.sec <-c (15, 30)을 설정하면 온도 그래프가 막대 플롯 위로 올라갑니다 (온도 축이 -75에서 시작됨) 하지만 각 그래프의 축은 여전히 ​​정확합니다.
Dag Hjermann

16

두 번째 기하 및 오른쪽 y 축에 적용되는 배율을 만들 수 있습니다. 이것은 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")
  )

여기에 이미지 설명을 입력하십시오

참고 : v3.0.0 사용ggplot2


14

이 도전의 해결책에 대한 기술 백본은 약 3 년 전에 Kohske 에 의해 제공되었습니다 [ KOHSKE ]. 솔루션과 관련된 주제와 기술은 여기에서 Stackoverflow [ID : 18989001, 29235405, 21026598]에 대한 몇 가지 사례에서 논의되었습니다. 따라서 위의 솔루션을 사용하여 특정 변형과 설명 연습 만 제공합니다.

우리가 일부 데이터해야합니까 가정 해 보자 Y1 그룹에서 G1 일부 데이터되는 Y2 그룹의 G2가 어떤 식 으로든 관련이있다, 예를 들어, 범위 / 규모 전환 또는 추가 약간의 소음. 따라서 왼쪽 에 y1 , 오른쪽에 y2 의 스케일로 하나의 플롯에 데이터를 함께 플롯하려고합니다 .

  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

이제 데이터를 다음과 같이 플롯하면

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())

더 작은 스케일 y1이 명백히 더 큰 스케일 y2에 의해 붕괴 됨에 따라 그것은 잘 정렬되지 않습니다 .

여기서 해결해야 할 트릭은 데이터 세트 를 기술적으로 첫 번째 스케일 y1 에 대해 플롯 하지만 두 번째 축에 대해 두 번째 축에 대해 원래 스케일 y2를 표시하는 레이블을보고하는 것 입니다.

따라서 표시 할 새 축의 기능을 계산하고 수집 하는 첫 번째 도우미 함수 CalcFudgeAxis 를 작성합니다. 이 기능은 취향에 맞게 수정 될 수 있습니다 (이것은 y2y1 범위에 매핑합니다 ).

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)
  ))
}

무엇을 산출 하는가?

> 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

이제 두 번째 도우미 함수 PlotWithFudgeAxis 에서 새 축의 ggplot 개체와 도우미 개체를 던지는 Kohske의 솔루션을 래핑했습니다.

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)
}

이제 모두 함께 넣어 수 있습니다 : 제안 된 솔루션은 일상적인 환경에서 어떻게 사용될 수 있는지 코드 쇼, 아래 . 플롯 호출은 이제 원래 데이터 y2를 더 이상 y1 의 스케일로 실행 되는 복제 된 버전 yf (사전 계산 된 도우미 객체 FudgeAxis 내부에 유지됨 )를 플롯 하지 않습니다 . 그런 다음 원래 ggplot objet을 Kohske의 도우미 함수 PlotWithFudgeAxis 로 조작하여 y2 스케일을 유지하는 두 번째 축을 추가합니다 . 또한 조작 된 플롯도 플롯합니다.

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)

이제 두 축을 사용하여 원하는대로 플롯 합니다 (왼쪽 y1 및 오른쪽 y2) .

2 축

위의 해결책은 똑바로 말하면 제한된 흔들리는 핵입니다. ggplot 커널과 함께 사용하면 사후 스케일 등을 교환한다는 경고가 표시됩니다.주의해서 처리해야하며 다른 설정에서 원하지 않는 동작이 발생할 수 있습니다. 또한 원하는대로 레이아웃을 얻기 위해 도우미 기능을 사용하여 둘러 봐야 할 수도 있습니다. 범례의 배치는 그러한 문제입니다 (패널과 새 축 사이에 배치되므로 이것이 떨어졌습니다). 2 축의 스케일링 / 정렬은 다소 까다로운 작업입니다. 위의 코드는 두 스케일 모두 "0"을 포함 할 때 잘 작동합니다. 그렇지 않으면 한 축이 이동합니다. 따라서 개선 할 수있는 기회로 정의하십시오 ...

에 그림을 저장하려면 호출을 장치 열기 / 닫기로 래핑해야합니다.

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

9

다음 기사는 ggplot2가 생성 한 두 개의 플롯을 단일 행에 결합하는 데 도움이되었습니다.

Cookbook for R의 한 페이지에 여러 그래프 표시 (ggplot2)

이 경우 코드는 다음과 같습니다.

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)

멀티 플롯 기능은 어떻게 되었습니까? ggplot2 라이브러리가 설치되어로드되었다는 사실에도 불구하고 함수를 찾을 수 없다는 오류가 발생합니다.
Nneka

1
@Danka 멀티 플롯 기능은 사용자 정의 기능입니다 (링크 된 페이지 하단에 있음).
Dribbel

줄거리를 추가 할 수 있습니까?
Sibo Jiang


7

나를 위해 까다로운 부분은 두 축 사이의 변환 함수를 파악하는 것이 었습니다. 나는 그것을 위해 myCurveFit 을 사용 했습니다.

> 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"
))

변형 함수 찾기

  1. y1-> y2 이 함수는 첫 번째 y 축에 따라 보조 y 축의 데이터를 "정규화"하도록 변환하는 데 사용됩니다.

여기에 이미지 설명을 입력하십시오

변환 기능 : f(y1) = 0.025*x + 2.75


  1. y2-> y1 이 함수는 첫 번째 y 축의 중단 점을 두 번째 y 축의 값으로 변환하는 데 사용됩니다. 이제 축이 교체되었습니다.

여기에 이미지 설명을 입력하십시오

변환 기능 : f(y1) = 40*x - 110


플로팅

ggplot호출 에서 변환 함수를 사용 하여 데이터를 "즉시" 변환하는 방법에 유의하십시오.

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") ) 

첫 번째 stat_summary호출은 첫 번째 y 축의 기준을 설정하는 호출입니다. 두 번째 stat_summary호출은 데이터를 변환하기 위해 호출됩니다. 모든 데이터는 첫 번째 y 축을 기준으로합니다. 따라서 첫 번째 y 축에 대해 데이터를 정규화해야합니다. 이를 위해 데이터에 변환 기능을 사용합니다.y=packetOkSinr*40 - 110

이제 두 번째 축을 변환하기 위해 scale_y_continuous 호출sec.axis=sec_axis(~.*0.025+2.75, name="y_second") .

여기에 이미지 설명을 입력하십시오


2
R은 이런 종류의 작업을 수행 할 수 coef(lm(c(-70, -110) ~ c(1,0)))coef(lm(c(1,0) ~ c(-70, -110))). 다음과 같은 도우미 함수를 정의 할 수 있습니다. 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

엡, 나는 알고있다 ... 단지 사이트가보다 직관적 것이라고 생각
user4786271

4

베이스 R 함수를 사용하여 이중 Y 축으로 플롯을 만들 수 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

facet_wrap(~ variable, ncol= )변수를 사용하여 새로운 비교를 만들 수 있습니다 . 축이 같지 않지만 비슷합니다.


1

나는 다른 y- 스케일이 "기본적으로 결함이있다"는 것을 hadley 와 다른 사람들에게 인정하고 동의한다 . 나는 종종 소원 - 그런 말로 미루어 보아, ggplot2이 기능을했다 - 특히, 데이터에있을 때 와이드 포맷 및 I 빠르게 시각화하거나 데이터를 확인하려면 (즉, 개인적인 용도 만 해당).

그동안 tidyverse라이브러리를 만드는 매우 쉽게 긴 형식으로 데이터를 변환하기 (있도록 facet_grid()아래와 같이, 프로세스가 여전히 사소한없는 의지 작업) :

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")

글을 쓰는 시점에서 ggplot2는 이미이를 통해이를 지원했습니다 sec_axis.
Konrad Rudolph

0

해들리 (Hadley)의 답변은 Stephen Few의 보고서에서 듀얼 스케일 축이 최고의 솔루션일까요? .

OP가 "counts"및 "rate"로 무엇을 의미하는지 모르지만 빠른 검색으로 Counts 및 Rates 가 표시되므로 North American Mountaineering 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

그런 다음 앞에서 언급 한 보고서의 7 페이지에서 제안한대로 거의 그래프를 만들려고 시도했습니다 (그리고 OP의 요청에 따라 카운트를 막대 차트로, 비율을 선 차트로 그래프로 표시).

시계열에만 적용되는 덜 분명한 다른 솔루션은 각 값과 참조 (또는 인덱스) 값 간의 백분율 차이를 표시하여 모든 값 집합을 공통 정량 척도로 변환하는 것입니다. 예를 들어, 그래프에 나타나는 첫 번째 간격과 같은 특정 시점을 선택하고 각 후속 값을 초기 값과의 백분율 차이로 표시하십시오. 아래 그림과 같이 각 시점의 값을 초기 시점의 값으로 나눈 다음 100을 곱하여 비율을 백분율로 변환합니다.

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))
  )

그리고 이것은 결과입니다 : 여기에 이미지 설명을 입력하십시오

그러나 나는 그것을 좋아하지 않으며 쉽게 그것에 전설을 넣을 수 없습니다 ...

1 윌리엄슨 드, 등. 2005 년 북미 Mountaineering 사고. Mountaineers Books, 2005.


0

간단한 질문 인 것처럼 보이지만 두 가지 근본적인 질문이 있습니다. A) 비교 차트에 제시하면서 다중 스칼라 데이터를 처리하는 방법 및 둘째, B) i) 용융 데이터, ii) 패싯, iii) 기존 레이어에 다른 레이어. 아래에 제시된 솔루션은 데이터를 재조정 할 필요없이 데이터를 다루므로 위의 두 조건을 모두 만족 시키며, 둘째로 언급 된 기술은 사용되지 않습니다.

결과는 다음과 같습니다. 더 나은 개선

이 방법에 대한 자세한 내용은 아래 링크를 참조하십시오. 데이터 크기를 조정하지 않고 막대가 나란히있는 2y 축 차트를 그리는 방법


0

나는이 답변 이 가장 도움 이 된다는 것을 알았지 만 올바르게 처리하지 못하는 것, 특히 부정적인 경우와 한계가 0 거리 인 경우 (우리가 잡으면 발생할 수 있음)가 있음을 발견했습니다. 데이터의 최대 / 최소 한도). 테스트 결과 이것이 일관되게 작동하는 것으로 보입니다.

다음 코드를 사용합니다. 여기서는 [y1, y2]로 변환하려는 [x1, x2]가 있다고 가정합니다. 내가 처리 한 방법은 [x1, x2]를 [0,1] (간단한 충분한 변환)으로 변환 한 다음 [0,1]을 [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)")  

여기서 중요한 부분은 2 차 y 축을 변환 ~((.-ylim.prim[1]) *b + ylim.sec[1])한 다음 실제 값에 역을 적용한다는 것 y = ylim.prim[1]+(Temp-ylim.sec[1])/b)입니다. 우리는 또한 그것을 보장해야합니다 limits = ylim.prim.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.