programing

각 면에 2개의 Y 축이 있고 척도가 서로 다른 gg 그림

oldcodes 2023. 6. 13. 22:46
반응형

각 면에 2개의 Y 축이 있고 척도가 서로 다른 gg 그림

선 를 한에 모두 , 둘 다 할 수 둘을 첫레이어의 즉, 보막비보차선는여주율을차합트하표야해니시다모를두차는나의첫두사에함트두용께가있를지하만수는지수가로으개할적행별모두지를면운카트를트여대주와▁i▁(▁chart▁of▁showing▁and▁a▁showingi▁i▁the▁all,▁chart첫▁a사함▁first▁rate▁line▁counts▁layer▁scale있두가수수용하께,를면geom_bar는 두 층( )에 됩니다.geom_line).

축을이수있까니습할동의 할 수 ?geom_line오른쪽으로?

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

여기에 이미지 설명 입력

ggplot2에서는 불가능합니다. 왜냐하면 개별 척도(서로의 변환인 주석 척도)가 있는 그래프는 근본적으로 결점이 있다고 생각하기 때문입니다.몇 가지 문제:

  • 플롯 공간의 점을 지정하면 데이터 공간의 점에 고유하게 매핑할 수 없습니다.

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

  • 이들은 쉽게 오도될 수 있습니다. 축의 상대적 척도를 지정할 수 있는 고유한 방법이 없으므로 조작에 노출됩니다.정크차트 블로그의 두 가지 예: 하나, 둘. 하나, .

  • 그들은 임의적입니다: 왜 3, 4 또는 10이 아닌 2개의 눈금만 가지고 있습니까?

또한 그래프의 이중 척도 축이 최고의 솔루션입니까?라는 주제에 대한 Stephen Few의 장황한 토론을 읽고 싶을 수도 있습니다.

때때로 고객은 y 척도 2개를 원합니다.그들에게 "결함이 있는" 연설을 하는 것은 종종 무의미합니다.하지만 저는 올바른 방법으로 일을 처리해야 한다는 ggplot2 주장을 좋아합니다.저는 ggplot이 실제로 일반 사용자에게 적절한 시각화 기술을 교육하고 있다고 확신합니다.

Faceting과 Scale free를 사용하여 두 데이터 시리즈를 비교할 수 있습니까? - 예: https://github.com/hadley/ggplot2/wiki/Align-two-plots-on-a-page

일반적인 사용 사례 이중 축이 있습니다. 예를 들어, 월간 온도와 강수량을 보여주는 기후 그래프가 있습니다.변수의 하한을 0이 아닌 다른 값으로 설정할 수 있도록 하여 메가트론의 솔루션에서 일반화된 간단한 솔루션은 다음과 같습니다.

예제 데이터:

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 <- ylim.prim[1] - b*ylim.sec[1]) # there was a bug here

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

온도를 선으로 표시하고 강수량을 막대 그래프로 표시하는 기후도

빨간색 선이 오른쪽 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)")

오른쪽 축에 색상을 지정합니다.

오른쪽에 빨간색 축이 있는 기후도

조정 가치가 있든지 을 통해 두 .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로 나누어야 합니다(및 형식 지정).그래서 위의 코드에서 중요한 부분은 정말입니다.*5~./5 sec_axis 값 sec_axis (sec_axis)를 ).5)까지

비교(여기서는 접근 방식을 판단하고 싶지 않습니다), 두 개의 차트가 서로 겹쳐지는 방식은 다음과 같습니다.

서로 위에 있는 두 개의 차트

어떤 것이 메시지를 더 잘 전달하는지 직접 판단할 수 있습니다("직장에서 사람들을 방해하지 마세요!").그것이 공정한 결정 방법이라고 생각합니다.

두 이미지 모두에 대한 전체 코드(위에 있는 것 이상은 아니며, 완료되어 실행할 준비가 되어 있음)는 여기에 있습니다. https://gist.github.com/sebastianrothbucher/de847063f32fdff02c83b75f59c36a7d 보다 자세한 설명은 여기에 있습니다. https://sebastianrothbucher.github.io/datascience/r/visualization/ggplot/2018/03/24/two-scales-ggplot-r.html

두 번째 검 및 오른쪽 y축에 적용되는 스케일링 계수를 생성할 수 있습니다.이것은 세바스찬의 해결책에서 나온 것입니다.

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

여기에 이미지 설명 입력

고참: 사용을 사용ggplot2 v3.0.0

여기 2차 축을 위한 변환 방법에 대한 제 의견이 있습니다.먼저 주 데이터와 보조 데이터의 범위를 연결하려고 합니다.이는 일반적으로 원하지 않는 변수로 인해 지구 환경을 오염시키는 측면에서 지저분합니다.

더 위해, 우리는 가지 기능을 공장을 것입니다. , 이더쉽게하위해두기생기만, 우리가는공것다입니들장입니다.scales::rescale()모든 무거운 물건을 들어 올립니다. 있기 에, 이들은폐기때에문을, 그만기환들때에문진어다대그, 있들그에것들한가니습억지고은것이의 ''을 가지고 있습니다.to그리고.from생성 전에 생성된 매개 변수입니다.

  • 한 가지 기능은 정방향 변환을 수행합니다. 즉, 보조 데이터를 1차 척도로 변환합니다.
  • 두 번째 기능은 역변환을 수행합니다. 즉, 1차 단위의 데이터를 2차 단위로 변환합니다.
library(ggplot2)
library(scales)

# Function factory for secondary axis transforms
train_sec <- function(primary, secondary, na.rm = TRUE) {
  # Thanks Henry Holm for including the na.rm argument!
  from <- range(secondary, na.rm = na.rm)
  to   <- range(primary, na.rm = na.rm)
  # Forward transform for the data
  forward <- function(x) {
    rescale(x, from = from, to = to)
  }
  # Reverse transform for the secondary axis
  reverse <- function(x) {
    rescale(x, from = to, to = from)
  }
  list(fwd = forward, rev = reverse)
}

이 모든 것이 다소 복잡해 보이지만, 기능 공장을 만들면 나머지 모든 것이 쉬워집니다.이제 그래프를 만들기 전에 공장에서 1차 데이터와 2차 데이터를 보여줌으로써 관련 기능을 생성하겠습니다.우리는 매우 다양한 범위를 가진 경제 데이터 세트를 사용할 것입니다.unemploy그리고.psavert

sec <- with(economics, train_sec(unemploy, psavert))

다음 는 그면우는을 사용합니다.y = sec$fwd(psavert)을 1차 축으로 하고, " " " " " 을 지정합니다.~ sec$rev(.)2차 축에 대한 변환 인수로 사용됩니다.이것은 1차 범위와 2차 범위가 그래프에서 동일한 공간을 차지하는 그래프를 제공합니다.

ggplot(economics, aes(date)) +
  geom_line(aes(y = unemploy), colour = "blue") +
  geom_line(aes(y = sec$fwd(psavert)), colour = "red") +
  scale_y_continuous(sec.axis = sec_axis(~sec$rev(.), name = "psavert"))

공장은 최대 크기를 조정하려는 경우 하한이 0인 데이터를 전달할 수 있기 때문에 이보다 약간 더 유연합니다.

# Rescaling the maximum
sec <- with(economics, train_sec(c(0, max(unemploy)),
                                 c(0, max(psavert))))

ggplot(economics, aes(date)) +
  geom_line(aes(y = unemploy), colour = "blue") +
  geom_line(aes(y = sec$fwd(psavert)), colour = "red") +
  scale_y_continuous(sec.axis = sec_axis(~sec$rev(.), name = "psavert"))

2021-02-05에 reprex 패키지에 의해 생성 (v0.3.0)

이 예에서 차이가 그렇게 뚜렷하지 않다는 것은 인정하지만 자세히 보면 최대값이 같고 빨간색 선이 파란색 선보다 더 낮아진다는 것을 알 수 있습니다.

편집:

이 접근 방식은 이제 ggh4x 패키지의 기능에서 캡처되고 확장되었습니다.고지 사항:저는 ggh4x의 저자입니다.

이 문제의 해결을 위한 기술적 백본은 Kohske가 약 3년 전에 제공했습니다 [KOHSKE].이 주제와 솔루션 관련 기술은 여기에 있는 스택 오버플로의 여러 사례에서 논의되었습니다 [ID: 1889001, 29235405, 21026598].따라서 위의 솔루션을 사용하여 구체적인 변화와 몇 가지 설명적인 설명만 제공할 것입니다.

그룹 G1의 일부 데이터 y1이 어떤 식으로든 관련되어 있다고 가정합니다. 예를 들어 범위/스케일 변환 또는 노이즈가 추가된 그룹 G2의 일부 데이터 y2와 관련이 있습니다.따라서 왼쪽에는 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를 나타내는 레이블을 사용하여 보조 축에 대해 보고하는 것입니다.

그래서 우리는 첫 번째 도우미 기능인 CalcFudge를 구축합니다.표시할 새 축의 형상을 계산하고 수집하는 축.함수는 y2를 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)
  ))
}

일부를 산출하는 것:

> 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

이제 두 번째 도우미 함수 PlotWithFudge에서 Kohske의 솔루션을 랩핑했습니다.(새 축의 ggplot 객체와 도우미 객체를 던지는 데 사용):

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의 도우미 기능 PlotWithFudge로 조작됩니다.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()

다음 문서는 ggplot2에 의해 생성된 두 개의 플롯을 단일 행에 결합하는 데 도움이 되었습니다.

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

저에게 까다로운 부분은 두 축 사이의 변환 함수를 알아내는 것이었습니다.는 그것을 위해 제 커브핏을 사용했습니다.

> 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축에 따라 "정규화"될 2차 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

두 제두 ▁▁opposite▁i▁now▁the다▁use▁the니사합▁transform▁axis▁to용▁second이제기 내에서 반대의 기능을 사용합니다.scale_y_continuous 호출:sec.axis=sec_axis(~.*0.025+2.75, name="y_second").

여기에 이미지 설명 입력

항상 방법이 있습니다.

이것은 크기를 조정하지 않고도 완전히 임의의 축을 사용할 수 있는 솔루션입니다.이 아이디어는 축을 제외하고 동일한 두 개의 플롯을 생성하고 그것들을 함께 해킹하는 것입니다.insert_yaxis_grob그리고.get_y_axiscowplot꾸러미

library(ggplot2)
library(cowplot)

## first plot 
p1 <- ggplot(mtcars,aes(disp,hp,color=as.factor(am))) + 
    geom_point() + theme_bw() + theme(legend.position='top', text=element_text(size=16)) +
    ylab("Horse points" )+ xlab("Display size") + scale_color_discrete(name='Transmitter') +
    stat_smooth(se=F)

## same plot with different, arbitrary scale   
p2 <- p1 +
    scale_y_continuous(position='right',breaks=seq(120,173,length.out = 3),
                       labels=c('little','medium little','medium hefty'))

ggdraw(insert_yaxis_grob(p1,get_y_axis(p2,position='right')))

두 개의 축이 있는 금기 플롯

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

그것은 겉보기에는 단순한 질문으로 보이지만 두 가지 근본적인 질문을 혼동합니다.비교 차트에 제시하면서 다중 스칼라 데이터를 다루는 방법, 둘째, B) i) 데이터 용해, ii) 페이싱, iii) 기존 레이어에 다른 레이어를 추가하는 것과 같은 R 프로그래밍의 일부 경험적 규칙 관행 없이 이를 수행할 수 있는지 여부.아래에 제시된 솔루션은 스케일 조정 없이 데이터를 처리하기 때문에 위의 조건을 모두 충족하며, 두 번째로 언급된 기술은 사용되지 않습니다.

여기 결과가 있습니다.

이 방법에 대해 더 알고 싶은 분들은 아래 링크를 따라주시기 바랍니다.데이터를 다시 축척하지 않고 막대를 나란히 사용하여 2-y 축 차트를 그리는 방법

사용할 수 있습니다.facet_wrap(~ variable, ncol= )변수에서 새 비교를 만듭니다.그것은 같은 축에 있지 않지만 유사합니다.

저는 별도의 y 척도가 "근본적으로 결함이 있다"는 것을 해들리(및 다른 사람들)와 인정하고 동의합니다.그런 말을 했지만, 저는 종종 소원을 빌었습니다.ggplot2이 기능이 있습니다. 특히 데이터가 광범위한 형식이고 데이터를 빠르게 시각화하거나 확인하고 싶을 때(즉, 개인 용도로만 사용).

그 동안에tidyverse긴▁that▁library만such다▁makes▁to▁(듭)으로 변환하는 것을 매우 쉽게 합니다.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")

는 이 답변이 저에게 가장 큰 도움이 되었지만, 특히 부정적인 경우와 제 한계가 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차 을 여서차중 2축 y변을것으로 입니다.~((.-ylim.prim[1]) *b + ylim.sec[1]) 값인 그런대 다 실 적 값 용 합 니 다 을 반 값 에 음 제 ▁they = ylim.prim[1]+(Temp-ylim.sec[1])/b)우리는 또한 확실히 해야 합니다.limits = ylim.prim.

다음은 Dag Hjermann의 기본 데이터와 프로그래밍을 통합하고, 플롯과 데이터 축을 최적으로 결합하기 위해 "변환 함수"를 생성하는 사용자 4786271의 전략을 개선하고, R 내에서 이러한 함수가 생성될 수 있다는 침례교의 주의에 응답합니다.

#Climatogram for Oslo (1961-1990)
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))

#y1 identifies the position, relative to the y1 axis, 
#the locations of the minimum and maximum of the y2 graph.
#Usually this will be the min and max of y1.
#y1<-(c(max(climate$Precip), 0))
#y1<-(c(150, 55))
y1<-(c(max(climate$Precip), min(climate$Precip)))

#y2 is the Minimum and maximum of the secondary axis data.
y2<-(c(max(climate$Temp), min(climate$Temp)))

#axis combines y1 and y2 into a dataframe used for regressions.
axis<-cbind(y1,y2)
axis<-data.frame(axis)

#Regression of Temperature to Precipitation:
T2P<-lm(formula = y1 ~ y2, data = axis)
T2P_summary <- summary(lm(formula = y1 ~ y2, data = axis))
T2P_summary   

#Identifies the intercept and slope of regressing Temperature to Precipitation:
T2PInt<-T2P_summary$coefficients[1, 1] 
T2PSlope<-T2P_summary$coefficients[2, 1] 


#Regression of Precipitation to Temperature:
P2T<-lm(formula = y2 ~ y1, data = axis)
P2T_summary <- summary(lm(formula = y2 ~ y1, data = axis))
P2T_summary   

#Identifies the intercept and slope of regressing Precipitation to Temperature:
P2TInt<-P2T_summary$coefficients[1, 1] 
P2TSlope<-P2T_summary$coefficients[2, 1] 


#Create Plot:
ggplot(climate, aes(Month, Precip)) +
  geom_col() +
  geom_line(aes(y = T2PSlope*Temp + T2PInt), color = "red") +
  scale_y_continuous("Precipitation", sec.axis = sec_axis(~.*P2TSlope + P2TInt, 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)")

가장 주목할 점은 새로운 "변환 기능"이 각 축의 데이터 세트에서 두 개의 데이터 포인트(일반적으로 각 세트의 최대값과 최소값)만 사용해도 더 잘 작동한다는 것입니다.두 회귀 분석의 결과 기울기와 절편을 통해 ggplot2는 각 축의 최소값과 최대값에 대한 그림을 정확하게 쌍으로 구성할 수 있습니다.사용자 4786271이 지적했듯이 두 회귀 분석은 각 데이터 세트와 플롯을 다른 데이터 세트로 변환합니다.첫 번째 y축의 중단점을 두 번째 y축의 값으로 변환합니다.두 번째는 첫 번째 y축에 따라 "정규화"될 보조 y축의 데이터를 변환합니다.다음 출력은 축이 각 데이터 세트의 최소값과 최대값을 정렬하는 방법을 보여줍니다.

여기에 이미지 설명 입력

최대값과 최소값이 일치하는 것이 가장 적합할 수 있지만, 이 방법의 또 다른 이점은 기본 축 데이터와 관련된 프로그래밍 라인을 변경하여 원하는 경우 보조 축과 관련된 플롯을 쉽게 이동할 수 있다는 것입니다.아래 출력은 y1 프로그래밍 라인의 최소 강수량 입력을 "0"으로 변경하여 최소 온도 레벨을 "0" 강수량 레벨과 정렬합니다.

시작: y1<-(c(max(climate$Precip)), min(climate$Precip))

종료: y1<-(c(max(climate$Precip), 0)

여기에 이미지 설명 입력

결과적으로 생성된 새 회귀 분석 및 ggplot2가 최소 온도를 "0" 강수량 수준의 새 "기준"에 정확하게 맞추기 위해 플롯과 축을 자동으로 조정한 방법에 주목합니다.마찬가지로 온도 그림을 쉽게 상승시켜 더 명확하게 표시할 수 있습니다.다음 그래프는 위에서 언급한 선을 다음으로 변경하여 생성됩니다.

"y1<-(c(150, 55))"

위의 선은 "150" 강수량 수준과 일치하는 온도 그래프의 최대값과 "55" 강수량 수준과 일치하는 온도 선의 최소값을 나타냅니다.ggplot2와 그에 따른 새 회귀 분석 출력을 통해 그래프가 축과 정확한 정렬 상태를 유지할 수 있는 방법을 다시 한 번 확인합니다.

여기에 이미지 설명 입력

위의 출력은 바람직한 출력이 아닐 수 있지만 그래프를 쉽게 조작할 수 있고 그래프와 축 사이에 올바른 관계를 유지하는 방법을 보여주는 예입니다.Dag Hjermann의 테마를 통합하면 그림에 해당하는 축을 식별할 수 있습니다.

여기에 이미지 설명 입력

해들리의 답변그래프의 이중 척도 축이 최고의 솔루션인가?라는 스티븐 퓨의 보고서에 대한 흥미로운 참조를 제공합니다.

OP가 "카운트"와 "레이트"로 무엇을 의미하는지는 모르겠지만 빠른 검색을 통해 카운트와 레이트를 확인할 수 있으므로 북미 산악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페이지에서 Few가 제안한 대로 그래프를 작성하려고 했습니다(그리고 카운트를 막대 그래프로 그래프화하고 비율을 선형 그래프로 그래프화하라는 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 WILLIAMSON, Jed, et al. Accidents in North American Mountaineering 2005. The Mountaineers Books, 2005.

언급URL : https://stackoverflow.com/questions/3099219/ggplot-with-2-y-axes-on-each-side-and-different-scales

반응형