두 서수 변수 사이의 관계에 대한 그래프


46

두 서수 변수 사이의 관계를 나타내는 적절한 그래프는 무엇입니까?

내가 생각할 수있는 몇 가지 옵션 :

  1. 임의의 지터가 추가 된 산점도는 서로 숨기는 지점을 중지합니다. 분명히 표준 그래픽-Minitab에서는이를 "개별 값 그림"이라고합니다. 내 의견으로는 데이터가 간격 스케일에서 온 것처럼 서수 레벨 사이의 일종의 선형 보간을 시각적으로 장려하므로 오도 될 수 있습니다.
  2. 산점도는 각 샘플링 단위에 대해 하나의 점을 그리는 것이 아니라 점의 크기 (면적)가 해당 레벨 조합의 빈도를 나타내도록 조정되었습니다. 나는 때때로 그러한 음모를 실제로 보았습니다. 그것들은 읽기 어려울 수 있지만 포인트는 규칙적으로 간격을 둔 격자에 놓여있어 데이터를 시각적으로 "간격"시키는 지터 스 캐터 플롯의 비판을 다소 극복합니다.
  3. 특히 변수 중 하나가 종속으로 처리되는 경우 독립 변수의 수준으로 그룹화 된 상자 그림이 표시됩니다. 종속 변수의 수준 수가 충분히 높지 않은 경우 (위스커가 없거나 매우 붕괴 된 사 분위수로 인해 "매우 평평"하지 않거나, 중앙값을 시각적으로 식별하는 것이 불가능한 악화 된 사 분위수) 경우 적어도 끔찍한 것처럼 보일 수 있지만, 서수 변수에 대한 관련 설명 통계.
  4. 주파수를 나타내는 열 맵이있는 값 표 또는 셀의 빈 격자. 시각적으로 다르지만 개념적으로 포인트 영역이 주파수를 나타내는 산점도와 유사합니다.

어떤 음모가 선호되는 다른 아이디어 나 생각이 있습니까? 특정 서수 대 좌표 그림이 표준으로 간주되는 연구 분야가 있습니까? (저는 유전체학에서 널리 퍼져있는 주파수 히트 맵을 기억하는 것 같지만 명목 대 명목에 대해서는 더 자주 의심됩니다.) 좋은 표준 참조 제안도 매우 환영받을 것입니다. 저는 Agresti에서 무언가를 추측하고 있습니다.

누군가 플롯으로 설명하고 싶다면 가짜 샘플 데이터에 대한 R 코드가 이어집니다.

"운동이 얼마나 중요합니까?" 1 = 전혀 중요하지 않음, 2 = 다소 중요하지 않음, 3 = 중요하지 않거나 중요하지 않음, 4 = 다소 중요 함, 5 = 매우 중요 함

"얼마나 정기적으로 10 분 이상 뛰나요?" 1 = 결코, 2 = 2 주일에 1 회 미만, 3 = 1 주 또는 2 주에 1 회, 4 = 주당 2 ~ 3 회, 주당 5 회 또는 4 회 이상.

"종종"을 종속 변수로 취급하고 "중요도"를 독립 변수로 취급하는 것이 당연한 경우, 도표가 둘을 구별하는 경우.

importance <- rep(1:5, times = c(30, 42, 75, 93, 60))
often <- c(rep(1:5, times = c(15, 07, 04, 03, 01)), #n=30, importance 1
           rep(1:5, times = c(10, 14, 12, 03, 03)), #n=42, importance 2
           rep(1:5, times = c(12, 23, 20, 13, 07)), #n=75, importance 3
           rep(1:5, times = c(16, 14, 20, 30, 13)), #n=93, importance 4
           rep(1:5, times = c(12, 06, 11, 17, 14))) #n=60, importance 5
running.df <- data.frame(importance, often)
cor.test(often, importance, method = "kendall") #positive concordance
plot(running.df) #currently useless

내가 찾은 연속 변수에 대한 관련 질문, 아마도 유용한 시작점 : 두 숫자 변수 사이의 관계를 연구 할 때 산점도의 대안은 무엇입니까?


1
spineplot은 어떻습니까?
Dimitriy V. Masterov

여러 그룹에 걸쳐 일 변량 서수 데이터 를 표시하기위한 관련 질문 도 관련이있을 수 있습니다. 서수 데이터 표시-평균, 평균 및 평균 순위
Silverfish

답변:


15

spineplot (모자이크 플롯)은 예제 데이터에 적합하지만 일부 범주 조합이 드물거나 존재하지 않으면 읽기 또는 해석하기 어려울 수 있습니다. 당연히 낮은 주파수는 작은 타일로 표시되고 전혀 타일이없는 것으로 표시되지만 심리적 어려움은 남아있을 수 있습니다. spineplot을 좋아하는 사람들이 논문이나 프리젠 테이션에 잘 맞는 예제를 선택하는 것도 당연하지만 대중에게 사용하기에는 너무 지저분한 예제를 종종 만들어 냈습니다. 반대로 spineplot은 사용 가능한 공간을 잘 사용합니다.

일부 구현은 대화식 그래픽을 전제로하여 사용자가 각 타일을 조사하여 자세한 정보를 얻을 수 있습니다.

상당히 잘 작동하는 대안은 양방향 막대 차트입니다 (다른 이름이 많이 있음).

예를 들어보기 tabplothttp://www.surveydesign.com.au/tipsusergraphs.html

이러한 데이터의 경우 가능한 하나의 도표 ( tabplotStata에서 사용하지만 적절한 소프트웨어에서는 쉬워야 함)는 다음과 같습니다.

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

이 형식은 개별 막대를 행 및 열 식별자에 쉽게 연관시킬 수 있으며 빈도, 비율 또는 백분율로 주석을 달 수 있습니다 (결과가 너무 바쁘다고 생각되면 그렇게하지 마십시오).

몇 가지 가능성 :

  1. 한 변수가 다른 변수에 대한 반응을 예측 변수로 생각할 수 있다면 평소와 같이 세로 축에 변수를 플로팅하는 것이 좋습니다. 여기서 "중요도"는 태도를 측정하는 것으로 생각하고, 문제는 그것이 행동에 영향을 미치는지 여부 ( "종종")입니다. 인과 적 문제는 이러한 가상의 데이터에서도 종종 더 복잡하지만 그 요점은 여전히 ​​남아 있습니다.

  2. 그 반대의 효과가 더 좋으면, 생각하고 해석하기가 더 쉬워지면 제안 # 1은 항상 우선합니다.

  3. 백분율 또는 확률 분석은 종종 의미가 있습니다. 원시 주파수 플롯도 유용 할 수 있습니다. (당연히이 플롯에는 두 종류의 정보를 한 번에 표시하는 모자이크 플롯의 미덕이 없습니다.)

  4. 물론 그룹화 된 막대 차트 또는 누적 막 대형 차트 (또는 WS Cleveland의 의미에서 여전히 흔하지 않은 그룹화 된 점 차트)의 (훨씬 더 일반적인) 대안을 시도 할 수 있습니다. 이 경우, 나는 그들이 잘 작동한다고 생각하지 않지만 때로는 더 잘 작동합니다.

  5. 일부는 다른 반응 범주를 다르게 색칠하고 싶을 수도 있습니다. 나는 이의를 제기하지 않았으며, 원한다면 이의를 진지하게 받아들이지 않을 것입니다.

그래프와 표를 혼성화하는 전략은 더 일반적으로 유용하거나 실제로는 원하는 것이 아닙니다. 종종 반복되는 주장은 그림과 표의 분리가 인쇄와 발명의 분열의 발명의 부작용 일 뿐이라는 점이다. 원고 작성자가 자신이 원하는 방식과 장소를 정확히 설명하는 것과 마찬가지로 필자가 다시 한 번 불필요합니다.


그래픽을 추가해 주셔서 감사합니다. 그래픽과 텍스트 데이터가 결합되는 방식에 대한 문제를 제기합니다. 일부 사람들은 막대 위에 숫자를 넣는 것을 좋아하지 않습니다. 막대가 실제보다 키가 커 보이기 때문에 인용 할 근거가 없습니다. 이것은 잘 알려진 의견이라고 생각합니다).
Silverfish

반면에 숫자의 위치를 ​​고정하면 두 가지 문제 중 하나가 발생하는 것 같습니다. 숫자가 막대에 겹쳐서 숨겨 지거나 막대 위의 숫자를 고정하면 아래쪽 막대에서 숫자가 "분리"될 수 있습니다. 특히. 어딘가에 이러한 문제에 대한 좋은 토론이 있습니까?
Silverfish

나는 당신이 참조가 필요하다고 생각하지 않습니다. 일반적인 태도입니다. 다른 변형이 있습니다 : (1) 디스플레이가 너무 바빠서 어수선한 것 같은 디스플레이 특정 제안. (2) 동일한 정보가 암시 적이므로 (또는 일부 명시 적에 따르면 숫자 텍스트가 중복된다는 개념에 호소 ) 어떤 식 으로든 그래프에서 (3) "소년은 파란색을 입고 여자는 분홍색을 입는다"는 태도는 숫자는 그림이고 표는 표이며, 트웨인도 만나야한다. (3) 나를 순수한 편견으로 쳤다. (2) 원칙적으로는 정확하지만 그럼에도 불구하고 숫자는 도움이 될 수 있습니다. (1) 예를 통해 생각해야합니다.
Nick Cox

나는 특정한 트레이드 오프에 대한 토론을 모른다. 숫자를 넣을 수 있도록 막대를 채색하지 않는 것이 좋습니다. 때로는 막대가 너무 작아서 항상이 작업을 수행 할 수 없습니다.
Nick Cox

30

히트 맵 에서 빠른 시도 가 있습니다. 블랙 셀 테두리를 사용하여 셀을 분리했지만 글렌 _b의 답변과 같이 타일을 더 많이 분리해야합니다.

히트 맵

library(ggplot2)
runningcounts.df <- as.data.frame(table(importance, often))
ggplot(runningcounts.df, aes(importance, often)) +
   geom_tile(aes(fill = Freq), colour = "black") +
   scale_fill_gradient(low = "white", high = "steelblue")

여기입니다 변동 플롯 앤디 W.에 의해 이전 의견에 따라 그가 그들 설명으로는 "그들은 기본적으로 그냥 범주 데이터에 대한 산점도를 비닝하고, 점의 크기는 그 빈 내에 관찰의 수에 매핑됩니다." 참조를 위해

Wickham, Hadley 및 Heike Hofmann. 2011 년 제품 플롯 . 시각화 및 컴퓨터 그래픽에 관한 IEEE 트랜잭션 (Proc. Infovis`11) . 사전 인쇄 PDF

변동 플롯

theme_nogrid <- function (base_size = 12, base_family = "") {
  theme_bw(base_size = base_size, base_family = base_family) %+replace% 
    theme(panel.grid = element_blank())   
}

ggplot(runningcounts.df, aes(importance, often)) +
  geom_point(aes(size = Freq, color = Freq, stat = "identity", position = "identity"), shape = 15) +
  scale_size_continuous(range = c(3,15)) + 
  scale_color_gradient(low = "white", high = "black") +
  theme_nogrid()

1
" 아마도 Glen_b의 답변에서와 같이 타일을 더 많이 분리해야합니다. "-이 경우에 필요한지 확실하지 않습니다. 여기서 범주를 연속적으로 보는 유혹이 훨씬 적습니다.
Glen_b

18

다음은 데이터의 spineplot이 어떻게 보이는지에 대한 예입니다. Stata 에서이 작업을 매우 빠르게 수행했지만 R 구현이 있습니다. R에서는 다음과 같아야한다고 생각합니다.

spineplot(factor(often)~factor(importance))

R 범주 형 변수를 제공하면 spineplot이 실제로 기본값으로 보입니다.

plot(factor(often)~factor(importance))

각 범주의 중요도에 대한 범주의 분수 분석이 종종 표시됩니다. 누적 막대는 종종 중요도 범주의 일부를 나타내는 세로 치수로 그려집니다. 가로 치수에는 각 중요도 범주의 분수가 표시됩니다. 따라서, 형성된 타일의 영역은 중요하고 종종 각 교차 조합에 대한 주파수, 또는 더 일반적으로 총계를 나타낸다.

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


1
나는 그것을 바꿨다.
Dimitriy V. Masterov

1
Nick Cox 인용 (Stata의 spineplot 작성자) : 두 변수에 대한 제한은 실제보다 더 분명합니다. 복합 변수는 둘 이상의 범주 형 변수를 교차 결합하여 만들 수 있습니다. 반응 변수는 일반적으로 y 축에 더 잘 표시됩니다. 하나의 변수가 이진 인 경우 y 축에 변수를 플로팅하는 것이 좋습니다. 당연히이 제안들 사이에는 약간의 긴장이있을 수 있습니다.
Dimitriy V. Masterov

3
위의 내용에 동의합니다. 그러나 Stata의 기본 색상 체계는 순서 변수에 비해 상당히 까다 롭습니다. 여러 가지 좋은 대안은 빨강 및 / 또는 파랑의 다른 음영이거나 gr {a | e} yscale 선택입니다.
Nick Cox

3
@Dimitriy 같은 상황에서 임의의 색상 혼합을 사용하는 것이 매우 이상하다고 생각합니다! 나는 정확한 색상으로 또는 수량화 된 것을 암시하거나 암시하지 않습니다. 그러나 요점은 등급이 매겨진 등급이 등급이 지정된 일련의 색상과 잘 일치한다는 것입니다. 열지도의 채색에는 실제로 임의의 주제가 있으며 실제로 많은 종류의 주제별지도 제작에 있습니다.
Nick Cox

2
색상이 뚜렷하지 않으면 등급이 매겨진 색상 구성표에 문제가 없습니다. 왜 보간하고 싶은 유혹을 받는가? 임의의 색상에 대한 논리를 볼 수 없습니다. 레인보우 시퀀스는 물리학에서는 의미가 있지만 사람들이 색상을 인식하는 방식 (예 : 노랑과 빨강이 너무 다르다)의 관점에서는 의미가 없습니다. 나는 선택을 통해 많은 학생들과 대화한다는 증거를 가지고 있으며, 80 %가 무지개 나 과일 샐러드보다 미묘한 등급의 시퀀스를 볼 때 "그게 훨씬 낫다"고 진심으로 말합니다. 옅은 파란색을 통해 옅은 빨간색을 통해 옅은 빨간색에서 빨간색으로 잘 작동합니다. 남성뿐만 아니라 여성에게도 시도하십시오.
Nick Cox

13

내가 한 방법은 약간의 퍼지이지만 쉽게 해결할 수 있습니다.

지 터링 방식의 수정 된 버전입니다.

축을 제거하면 스케일을 연속으로 해석하려는 유혹이 줄어 듭니다. 지터가있는 조합 주위의 상자 그리기는 "스케일 구분"과 같은 것이 있다는 것을 강조합니다.

이상적으로는 1..5 레이블을 범주 이름으로 바꿔야하지만 지금은 상상을 위해 그대로 두겠습니다. 나는 그것이 그 의미를 전달한다고 생각합니다.

 plot(jitter(often)~jitter(importance),data=running.df,bty="n",
    ylim=c(0.5,5.5),xlim=c(0.5,5.5),cex=0.5,pty="s",xaxt="n",yaxt="n") 
 axis(1,tick=TRUE,col=0)
 axis(2,tick=TRUE,col=0)
 rect(rep(seq(0.75,4.75,1),5),rep(seq(0.75,4.75,1),each=5),
       rep(seq(1.25,5.25,1),5),rep(seq(1.25,5.25,1),each=5),
       border=8)

지터 서수-음모


가능한 개선 사항 :

i) 나누기를 더 작게 만들기 (개인적으로 이보다 더 큰 나누기를 선호 함)

ii) 상자 내에서 겉보기 패턴의 발생률을 줄이기 위해 유사 시퀀스를 사용하려고 시도합니다. 내 시도가 다소 도움이되었지만 더 적은 수의 점이있는 셀에는 여전히 상관 관계가있는 하위 시퀀스가 ​​여전히 있음을 알 수 있습니다 (예 : 맨 위 행의 상자, 두 번째 열). 이를 방지하기 위해 하위 상자 마다 준 무작위 시퀀스를 초기화해야 할 수도 있습니다 . (라틴 하이퍼 큐브 샘플링이 대안이 될 수 있습니다.) 일단 정렬되면 지터와 똑같이 작동하는 함수에 삽입 될 수 있습니다.

준 랜덤 지터 및 더 큰 상자

library("fOptions")

 hjit <- runif.halton(dim(running.df)[1],2) 
 xjit <- (hjit[,1]-.5)*0.8
 yjit <- (hjit[,2]-.5)*0.8  

 plot(I(often+yjit)~I(importance+xjit),data=running.df,bty="n",
    ylim=c(0.5,5.5),xlim=c(0.5,5.5),cex=0.5,pty="s",xaxt="n",yaxt="n") 
 axis(1,tick=TRUE,col=0)
 axis(2,tick=TRUE,col=0)
 rect(rep(seq(0.55,4.55,1),5),rep(seq(0.55,4.55,1),each=5),
       rep(seq(1.45,5.45,1),5),rep(seq(1.45,5.45,1),each=5),
       border=8)

1
나는 이것을 좋아한다. 나에게 분리는 실제로 데이터의 서수를 강조한다! 불행하게도 사람의 눈은 지 터링에서 명백한 패턴으로 자연스럽게 그려집니다 (예 : 패널 (4,5) 및 (5,3)의 "상향 추세"). 더하기 측면에서 "점수 계산"은 도트 크기로 주파수를 판단하는 것보다 훨씬 자연 스럽습니다. "지터 경향"을 산만하게하지 않기 위해 중앙에 점이 고르게 간격을 두거나 규칙적인 패턴으로 뭉쳐지는 변형이 있습니까?
Silverfish

1
지리학에서 유사한 개념 인 @Silverfish는 도트 밀도 맵입니다. 지리학자들은 일정한 양의 공백을 채우는 규칙적인 패턴이나 패턴 (임의의 간격보다 먼 간격)이 관찰자 사이에서보다 정확한 인식을 생성하는 경향이 있다는 증거를 발견했습니다.
Andy W

IMO는 좋은 생각이지만이 예제에서는 패널 사이의 간격이 너무 커서 모든 추세를 시각화하기가 매우 어렵습니다. 치료법은 질병보다 나쁩니다 (그러나 패널을 훨씬 더 가깝게 만드는 것은 꽤 쉬워야합니다).
Andy W

1
@silverfish 준 무작위 지 터링은 그에 대한 가능한 해결책이 될 것입니다. 당신의 관심사는 제가 가진 것입니다.
Glen_b

1
아주 좋아요! IMO 이것은이 경우 spineplot보다 더 나은 옵션입니다 (척추 또는 모자이크 플롯은 모든 범주 쌍에 대한 조건부 분포를 평가하는 것이 좋습니다-이 지터가있는 도트 플롯은 경향을 평가하기가 더 쉽습니다-데이터의 순서 특성을 활용하고 일부를 가정 함) 단조로운 관계의 유형).
Andy W

7

R 패키지 리버 플롯 사용 :

  data$importance <- factor(data$importance, 
                            labels = c("not at all important",
                                       "somewhat unimportant",
                                       "neither important nor unimportant",
                                       "somewhat important",
                                       "very important"))
  data$often <- factor(data$often, 
                       labels = c("never",
                                  "less than once per fortnight",
                                  "once every one or two weeks",
                                  "two or three times per week",
                                  "four or more times per week"))

  makeRivPlot <- function(data, var1, var2, ...) {

    require(plyr)
    require(riverplot)
    require(RColorBrewer)

    names1 <- levels(data[, var1])
    names2 <- levels(data[, var2])

    var1 <- as.numeric(data[, var1])
    var2 <- as.numeric(data[, var2])

    edges <- data.frame(var1, var2 + max(var1, na.rm = T))
    edges <- count(edges)

    colnames(edges) <- c("N1", "N2", "Value")

    nodes <- data.frame(ID     = c(1:(max(var1, na.rm = T) +
                                      max(var2, na.rm = T))),
                        x      = c(rep(1, times = max(var1, na.rm = T)),
                                   rep(2, times = max(var2, na.rm = T))),
                        labels = c(names1, names2) ,
                        col    = c(brewer.pal(max(var1, na.rm = T), "Set1"),
                                   brewer.pal(max(var2, na.rm = T), "Set1")),
                        stringsAsFactors = FALSE)

    nodes$col <- paste(nodes$col, 95, sep = "")

    return(makeRiver(nodes, edges))

  }

a <- makeRivPlot(data, "importance", "often")

riverplot(a, srt = 45)

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


1
(+1) 나는 이것을 위해 평행 좌표 를 사용하는 아이디어를 좋아합니다 ! 다이어그램을 통해 경로를 추적하는 것이 더 쉬울 것이라고 생각합니다. 색상이 왼쪽에서 오른쪽으로 흐르면 "종종"답변이 어떻게 분해되는지 봅니다 ( "종종"을 종속 변수로 효과적으로 표시하고 " "설명 변수로서의 중요성"). 이러한 플롯의 일부 대화식 구현 에서는 축을 클릭하여 해당 변수로 색상을 지정할 수 있습니다.
Silverfish

1
비교를 위해 범주 형 데이터 용으로 설계된 Robert Kosara의 "병렬 세트"시각화 는 색상이 다이어그램을 통해 흐릅니다.
Silverfish

6

내가 원래 생각하지 않은 다른 생각은 체 플롯 이었습니다.

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

각 타일의 크기는 예상 빈도에 비례합니다. 사각형 안의 작은 사각형은 실제 주파수를 나타냅니다. 따라서 제곱의 밀도가 클수록 예상 주파수보다 높음을 나타냅니다 (파란색으로 표시됨). 낮은 제곱 밀도 (빨간색)는 예상 주파수보다 낮습니다.

색상이 잔차의 부호가 아니라 크기를 나타내는 경우 선호한다고 생각합니다. 예상 주파수와 관측 주파수가 비슷하고 잔차가 0에 가까운 에지의 경우에 특히 그렇습니다. 이분법적인 빨간색 / 파란색 체계는 작은 편차를 지나치게 강조하는 것으로 보입니다.

R 구현 :

library(vcd)
runningcounts.df <- as.data.frame(table(importance, often))
sieve(Freq ~ often + importance, data=runningcounts.df, shade= TRUE)

1
색상이 기호뿐만 아니라 크기를 나타내는 선호도와 관련하여 한 가지 가능성은 예상과의 차이가 상대적으로 작을 때 색상을 더 회색으로 만드는 것입니다.
Glen_b

6

R의다면 막대 차트는 각 레벨의 "중요도"에서 "종종"분포를 매우 명확하게 보여줍니다. 그러나 "중요도"수준에 따라 최대 개수가 더 다양하면 제대로 작동하지 않았을 것입니다. 빈 공간을 많이 피하기 위해 scales="free_y"ggplot ( 여기 참조 ) 에서 설정하기 가 쉽지만 막대 모양이 너무 작아서 저주파수 레벨의 "중요도"에서 분포 모양을 식별하기가 어렵습니다. 이러한 상황에서는 세로 축에 상대 주파수 (조건부 확률)를 대신 사용하는 것이 좋습니다.

패싯 막대 차트

Nick Cox가 연결 한 Stata 의 tabplot만큼 "깨끗하지" 않지만 유사한 정보를 전달합니다.

R 코드 :

library(ggplot)
running2.df <- data.frame(often = factor(often, labels = c("never", "less than once per fortnight", "once every one or two weeks", "two or three times per week", "four or more times per week")), importance = factor(importance, labels = c("not at all important", "somewhat unimportant", "neither important nor unimportant", "somewhat important", "very important")))
ggplot(running2.df, aes(often)) + geom_bar() +
  facet_wrap(~ importance, ncol = 1) +
  theme(axis.text.x=element_text(angle = -45, hjust = 0)) +
  theme(axis.title.x = element_blank())
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.