R로 태국 음식 시각화하기

이 게시물은 태국 음식 요리 시리즈의 2부입니다.

데이터 정리



데이터 정리는 일반적으로 비선형적입니다.

우리는 탐색하기 위해 데이터를 조작하고, 데이터에 대해 배우고, 특정 항목을 정리해야 하는지 확인하거나 경우에 따라 Python으로 돌아가 다시 긁어냅니다. 컬럼a1a6는 탐색 및 정리 과정에서 발견된 누락된 데이터로 인해 다른 컬럼과 다르게 스크랩되었습니다.

특정 링크의 경우 .find(text=True) 사용이 의도한 대로 작동하지 않아 약간의 조정이 이루어졌습니다.

이 게시물에서 R는 데이터 정리를 위해 선택한 도구입니다.

다른 데이터 정리 작업은 다음과 같습니다.
  • 열 이름 변경(스네이크 케이스)

  • # read data
    df <- read_csv("thai_dishes.csv")
    
    # change column name
    df <- df %>%
        rename(
            Thai_name = `Thai name`,
            Thai_name_2 = `Thai name 2`,
            Thai_script = `Thai script`,
            English_name = `English name`
        )
    
    


  • 개행 이스케이프 시퀀스(\n)를 제거합니다.

  • # remove  \n from all columns ----
    df$Thai_name <- gsub("[\n]", "", df$Thai_name)
    df$Thai_name_2 <- gsub("[\n]", "", df$Thai_name_2)
    df$Thai_script <- gsub("[\n]", "", df$Thai_script)
    df$English_name <- gsub("[\n]", "", df$English_name)
    df$Image <- gsub("[\n]", "", df$Image)
    df$Region <- gsub("[\n]", "", df$Region)
    df$Description <- gsub("[\n]", "", df$Description)
    df$Description2 <- gsub("[\n]", "", df$Description2)
    


  • 새 열 추가/변경(major_groupings, minor_groupings):

  • # Add Major AND Minor Groupings ----
    df <- df %>%
        mutate(
            major_grouping = as.character(NA),
            minor_grouping = as.character(NA)
            )
    


  • Thai_name 열에서 누락된 데이터에 대한 행 편집: 26, 110, 157, 234-238, 240, 241, 246

  • 참고: 이것은 a1a6 스크랩 방법을 변경한 후 첫 번째 라운드에만 필요했으며 이 단계는 더 이상 필요하지 않습니다.

    # If necessary; may not need to do this after scraping a1 and a6 - see above
    # Edit Rows for missing Thai_name
    df[26,]$Thai_name <- "Khanom chin nam ngiao"
    df[110,]$Thai_name <- "Lap Lanna"
    df[157,]$Thai_name <- "Kai phat khing"
    df[234,]$Thai_name <- "Nam chim chaeo"
    df[235,]$Thai_name <- "Nam chim kai"
    df[236,]$Thai_name <- "Nam chim paesa"
    df[237,]$Thai_name <- "Nam chim sate"
    df[238,]$Thai_name <- "Nam phrik i-ke"
    df[240,]$Thai_name <- "Nam phrik kha"
    df[241,]$Thai_name <- "Nam phrik khaep mu"
    df[246,]$Thai_name <- "Nam phrik pla chi"
    


  • "edit_thai_dishes.csv"에 저장

  • # Write new csv to save edits made to data frame
    write_csv(df, "edit_thai_dishes.csv")
    


    데이터 시각화



    데이터를 시각화하는 방법에는 여러 가지가 있습니다. 태국 요리의 다양성을 알리고 싶기 때문에 팟타이 외에도 많은 옵션을 캡처하는 시각화가 필요합니다.

    저는 덴드로그램을 선택했습니다. 이 그래프는 그룹화 및 하위 그룹화로 요리를 구성할 수 있기 때문에 프로젝트에 적합한 데이터 내의 계층 구조를 가정합니다.

    태국 요리를 어떻게 정리할 수 있을까요?



    우리는 먼저 팟타이가 최고의 개별 요리에 가깝지 않다는 것을 보여주기 위해 개별 요리와 공유 요리를 구분합니다. 실제로 더 많은 요리가 공유 그룹에 속합니다.

    하나의 시각적 개체에 너무 많은 데이터를 넣는 것을 방지하기 위해 개별 요리와 공유 요리에 대해 두 가지 별도의 시각화를 만듭니다.

    다음은 팟타이에 대한 52가지 개별 요리 대안을 나타내는 첫 번째 덴드로그램입니다.



    덴드로그램을 생성하려면 ggraphigraph 라이브러리를 사용해야 합니다. 먼저 개별 요리를 필터링하여 라이브러리를 로드하고 데이터 프레임을 하위 설정합니다.

    df <- read_csv("edit_thai_dishes.csv")
    
    library(ggraph)
    library(igraph)
    
    df %>%
        select(major_grouping, minor_grouping, Thai_name, Thai_script) %>%
        filter(major_grouping == 'Individual dishes') %>%
        group_by(minor_grouping) %>%
        count() 
    
    


    개별 요리(예: Rice, Noodles 및 Misc) 내에서 하위 그룹을 만들기 위해 가장자리와 노드(예: from 및 to)를 만듭니다.

    # Individual Dishes ----
    
    # data: edge list
    d1 <- data.frame(from="Individual dishes", to=c("Misc Indiv", "Noodle dishes", "Rice dishes"))
    
    d2 <- df %>%
        select(minor_grouping, Thai_name) %>%
        slice(1:53) %>%
        rename(
            from = minor_grouping,
            to = Thai_name
        ) 
    
    edges <- rbind(d1, d2)
    
    # plot dendrogram (idividual dishes)
    indiv_dishes_graph <- graph_from_data_frame(edges)
    
    ggraph(indiv_dishes_graph, layout = "dendrogram", circular = FALSE) +
        geom_edge_diagonal(aes(edge_colour = edges$from), label_dodge = NULL) +
        geom_node_text(aes(label = name, filter = leaf, color = 'red'), hjust = 1.1, size = 3) +
        geom_node_point(color = "whitesmoke") +
        theme(
            plot.background = element_rect(fill = '#343d46'),
            panel.background = element_rect(fill = '#343d46'),
            legend.position = 'none',
            plot.title = element_text(colour = 'whitesmoke', face = 'bold', size = 25),
            plot.subtitle = element_text(colour = 'whitesmoke', face = 'bold'),
            plot.caption = element_text(color = 'whitesmoke', face = 'italic')
        ) +
        labs(
            title = '52 Alternatives to Pad Thai',
            subtitle = 'Individual Thai Dishes',
            caption = 'Data: Wikipedia | Graphic: @paulapivat'
        ) +
        expand_limits(x = c(-1.5, 1.5), y = c(-0.8, 0.8)) +
        coord_flip() +
        annotate("text", x = 47, y = 1, label = "Miscellaneous (7)", color = "#7CAE00")+
        annotate("text", x = 31, y = 1, label = "Noodle Dishes (24)", color = "#00C08B") +
        annotate("text", x = 8, y = 1, label = "Rice Dishes (22)", color = "#C77CFF") +
        annotate("text", x = 26, y = 2, label = "Individual\nDishes", color = "#F8766D")
    


    다양한 요리를 구성하는 가장 좋은 방법은 무엇입니까?



    개별 요리보다 약 4배 많은 공유 요리가 있으므로 덴드로그램은 모든 요리의 이름을 하나의 그래픽에 맞도록 원형이어야 합니다.

    이러한 유형의 시각적 개체에 정기적으로 사용하는 멋진 리소스는 R Graph Gallery 입니다. 텍스트 각도를 계산하는 방법에 약간의 문제가 있어서 PR to fix을 제출했습니다.

    개별 요리와 공유 요리를 구분하는 것이 너무 조잡할 수 있습니다. 201개의 공유 태국 요리에 대한 덴드로그램 내에서 카레, 소스/페이스트, 찜, 구이, 튀김, 튀김 및 볶음, 샐러드, 수프 및 기타 기타:



    # Shared Dishes ----
    df %>%
        select(major_grouping, minor_grouping, Thai_name, Thai_script) %>%
        filter(major_grouping == 'Shared dishes') %>%
        group_by(minor_grouping) %>%
        count() %>%
        arrange(desc(n))
    
    d3 <- data.frame(from="Shared dishes", to=c("Curries", "Soups", "Salads",
                                                "Fried and stir-fried dishes", "Deep-fried dishes", "Grilled dishes",
                                                "Steamed or blanched dishes", "Stewed dishes", "Dipping sauces and pastes", "Misc Shared"))
    
    
    d4 <- df %>%
        select(minor_grouping, Thai_name) %>%
        slice(54:254) %>%
        rename(
            from = minor_grouping,
            to = Thai_name
        )
    
    edges2 <- rbind(d3, d4)
    
    # create a vertices data.frame. One line per object of hierarchy
    vertices = data.frame(
        name = unique(c(as.character(edges2$from), as.character(edges2$to)))
    )
    
    # add column with group of each name. Useful to later color points
    vertices$group = edges2$from[ match(vertices$name, edges2$to)]
    
    # Add information concerning the label we are going to add: angle, horizontal adjustment and potential flip
    # calculate the ANGLE of the labels
    vertices$id=NA
    myleaves=which(is.na(match(vertices$name, edges2$from)))
    nleaves=length(myleaves)
    vertices$id[myleaves] = seq(1:nleaves)
    vertices$angle = 360 / nleaves * vertices$id + 90    
    
    
    # calculate the alignment of labels: right or left
    vertices$hjust<-ifelse( vertices$angle < 275, 1, 0)
    
    
    
    # flip angle BY to make them readable
    vertices$angle<-ifelse(vertices$angle < 275, vertices$angle+180, vertices$angle)
    
    # plot dendrogram (shared dishes)
    shared_dishes_graph <- graph_from_data_frame(edges2)
    
    ggraph(shared_dishes_graph, layout = "dendrogram", circular = TRUE) +
        geom_edge_diagonal(aes(edge_colour = edges2$from), label_dodge = NULL) +
        geom_node_text(aes(x = x*1.15, y=y*1.15, filter = leaf, label=name, angle = vertices$angle, hjust= vertices$hjust, colour= vertices$group), size=2.7, alpha=1) +
        geom_node_point(color = "whitesmoke") +
        theme(
            plot.background = element_rect(fill = '#343d46'),
            panel.background = element_rect(fill = '#343d46'),
            legend.position = 'none',
            plot.title = element_text(colour = 'whitesmoke', face = 'bold', size = 25),
            plot.subtitle = element_text(colour = 'whitesmoke', margin = margin(0,0,30,0), size = 20),
            plot.caption = element_text(color = 'whitesmoke', face = 'italic')
        ) +
        labs(
            title = 'Thai Food is Best Shared',
            subtitle = '201 Ways to Make Friends',
            caption = 'Data: Wikipedia | Graphic: @paulapivat'
        ) +
        #expand_limits(x = c(-1.5, 1.5), y = c(-0.8, 0.8)) +
        expand_limits(x = c(-1.5, 1.5), y = c(-1.5, 1.5)) +
        coord_flip() +
        annotate("text", x = 0.4, y = 0.45, label = "Steamed", color = "#F564E3") +
        annotate("text", x = 0.2, y = 0.5, label = "Grilled", color = "#00BA38") +
        annotate("text", x = -0.2, y = 0.5, label = "Deep-Fried", color = "#DE8C00") +
        annotate("text", x = -0.4, y = 0.1, label = "Fried &\n Stir-Fried", color = "#7CAE00") +
        annotate("text", x = -0.3, y = -0.4, label = "Salads", color = "#00B4F0") +
        annotate("text", x = -0.05, y = -0.5, label = "Soups", color = "#C77CFF") +
        annotate("text", x = 0.3, y = -0.5, label = "Curries", color = "#F8766D") +
        annotate("text", x = 0.5, y = -0.1, label = "Misc", color = "#00BFC4") +
        annotate("text", x = 0.5, y = 0.1, label = "Sauces\nPastes", color = "#B79F00")
    
    


    데이터 과학, R, Python, SQL 등에 대한 자세한 내용은 .

    좋은 웹페이지 즐겨찾기