顯示具有 R program 標籤的文章。 顯示所有文章
顯示具有 R program 標籤的文章。 顯示所有文章

2023年1月28日 星期六

EDA|2020-2023 YouTube 美國篇 現在才知道 BTS 和 BLACK PINK 這麼紅

前陣子有點沈迷於 Kaggle 上的資料分析,有一個 YouTube 的發燒榜資料滿齊的,有從 2020 年開始到現在的發燒影片資料,每天都有更新,目前有美加、日韓等等國家的資料,好奇其他國家都在看什麼,於是想說用 R 來分析一下。

我只分析了美加日三個國家,可惜沒台灣的資料,不然也想看看。

資料庫來源:YouTube Trending Video Dataset (updated daily)

這篇先用美國的,程式碼以 Markdown 的方式放在下面連結。

R Markdown: YouTube trending video data (1) - US

先來看看哪個種類的影片最常上發燒和最多人觀看。



最受歡迎的影片以娛樂和遊戲為主,看看有哪些頻道上一年可以上發燒超過兩百次。



裡面好幾個沒聽過,孤狗了一下後發現:
The Game Theorists, SSundee, MrBeast Gamming, Fortnite -- 遊戲
SSSniperWolf, Ryan Trahan, MrBeast, Dude Perfect -- 網紅 YouTubers
Sunday Night Live -- 夜夜秀之類的節目吧
NFL, NBC Sports, NBA, ESPN -- 大家都知道的體育頻道
Marvel Entertainment - 你知道的,就是一堆超人的那個。



令人意想不到的是上發燒最多次數的影片竟然是 SpaceX 的 Starlink Mission!



最多觀看次數的前一百名頻道以音樂頻道和短影片為主,HYBE LABELS 和 Big Hit Labels 是防彈少年團 BTS 的經紀公司,Big Hit Labels 之後改名為 HYBE LABELS。

FFUNTV 和 Fortnite Fun TV 好像是同一個,也是個網紅 YouTubers,都是不到五分鐘的沒對話短影片,但是訂閱數有近一千四百萬。CHANDAN ART ACADEMY 同樣是網紅 YouTuber 的樣子,也都是不到五分鐘的短影片,以畫畫為主,不知道是哪國人,影片的名字都看不懂。之前聽幾位 YouTubers 說官方近兩年在推長影片,短影片看起來是表叫消退。

Bizarrap 是音樂頻道,裡面都是他製作的歌。Adele 和 BLACK PINK 就不用說了,是說我看了這個資料庫後才發現,BLACK PINK 這麼紅,BTS 紅成這樣已經夠讓我驚呆了。



看看最多觀看次數的影片前一百名,光是 BTS 和 BLACK PINK 就佔了超過一半,韓團紅成這樣真是驚人。

如果除掉那些音樂、電視電影和短影片呢?這三年來最高觀看的幾個頻道有哪些。



去年崛起的印度製片公司 YRF,遊戲頻道 The Pixel Kingdom 只紅了 2020 年,另一個遊戲頻道 Technoblade 只紅了去年一年,今年還不知道。MrBeast 似乎有點下降。BLACK PINK 主要在 2021 年。Alex & Ksyu 算是網紅 YouTubers,以不到五分鐘的短影片為主,也是去年開就消退了。



如果看每年的前五十名,今年起來的有 BLACK PINK 經紀公司 YG Entertainment,驚人的是韓國的 행복지수 103% 也不過兩隻片,三個禮拜而已,現在已經三百萬訂閱了?!孤狗了一下,原來是位 Ig 有六千八百萬追蹤的網紅。(不過她是誰啊?)

只能說,韓國這幾年的娛樂產業太強了,能做到這樣真是佩服。












2022年7月31日 星期日

Google 的 Data Analytics 課程

去年年底的時候,想說耶誕假在家沒事,可以開啟 Coursera 七天免費的活動,於是就上了看起來很多人推薦的 Python for Everybody (PY4E)。課程還不錯,算是有系列的學習,之後可以自己活用,但是因為很長,一個禮拜其實上不完,那時候繼續上的話費用有 discount,所以就繼續上,又想說既然付費了,就上一下其他的課程。會上 Google Data Analytics 是因為看到 YT 有人介紹,所以就上上看。

基本上 Google 把資料分析分成六個階段,每個階段用一堂課介紹。六個階段分別為:

1. Ask: 你要回答的問題是什麼?
2. Prepare: 準備你的 data,包括資料來源、可信度等等。
3. Processs: 清理資料,主要是看有沒有錯誤或是缺少的地方,如果有就把它清乾淨。
4. Analyze: 用各種軟體分析資料,這個課程主要是教用 Google Spreadsheet, SQL, RStudio 和 Tableau。
5. Share: 分享你的分析結果,可以分享在 Google site, Kaggle, GitHub, Tableau,或是自己的部落格。
6. Act: 應用你的分析結果,因為通常是以商業分析為主,所以應用的部分就是怎麼把你的分析應用在商業上,例如怎麼增加客群之類的。



最後堂是 Capstone,也就是 Case Study,挑一個做,然後分享在你選擇的平台。

前面的 Ask 和 Prepare 過程其實只是教一個概念,像是如何找出你要回答的問題,你要如何解決問題?簡單來講就是研究所的思考訓練,如果你是研究生,這個部分其實就是你天天在做的事情,而 Spreadsheet, SQL, RStudio 和 Tableau 就是用來分析工具,就像是 WB 和 IF 等等,只是在 data science 你的工具是 SQL 和 RStudio。

不過這堂課程主要是著重在思考,試著讓你了解怎麼去找出問題的答案,所以在技術上的著墨不是很深入,Google 比較像是希望給你一個開頭,然後深入的技術上問題你自己去 stackoverflow 或其他平台上問,所以它也常強調你要如何在論壇上有禮貌、有技術的問問題。我的 SQL 主要是在 Python for Everybody 這堂課學的(沒錯,它後面也有教 SQL!)RStudio 則是之前在 UBC 學的,還有額外的自學,我也把筆記都放在這個部落格了,搜尋 R program 這個 tag 就有很多篇。

我最後是把 Capstone 的 case study 分享在 Kaggle,上面有各種 data science 的分享,你可以看到別人的思考過程,他們是怎麼做資料分析的。當然,你也可以做成 R Markdown 分享在 GitHub 或自己的網站。


R Markdown: Fitbit case study
R html: Fitbit case study











2018年3月31日 星期六

R | ggplot: 整理圖的外觀 - scale, legend

會畫一些基本的圖了以後,這篇要介紹怎麼整理圖的外觀,例如改變兩軸的 scales 或是加標示(legend)等等,讓圖看起來比較清楚又簡單易懂。

關於這篇的課堂講義請看這:R Graphics with Ggplot2 - Day 2

這邊同要需要先跑下面這些 library。

library(ggplot2)
library(dplyr)
data(mpg)
data(diamonds)

同樣是用檔案資料 mpg,下面之前設好的 p1。(解說看這篇

p1 <- ggplot(mpg, aes(displ, hwy))
p1 + geom_point(alpha = 1/5)



可以改變兩軸的名稱,只要在後面加這個:scale_x_continuous(" ")scale_y_continuous(" "),然後在 " " 裡面打入你想要的軸名就好了。

p1 + geom_point(alpha = 1/5) +
   scale_x_continuous("Engine displacement (L)") +
   scale_y_continuous("Highway mileage (miles/gallon)")



或是也可以簡單點用:xlab(' ')ylab(' '),然後在 ' ' 裡面打你要的軸名。

如果要加上圖的名稱或標題,則是在加上:ggtitle(' ')

p1 + geom_point(alpha = 1/5) +
   xlab('Engine displacement (L)') +
   ylab('Highway mileage (miles/gallon)') +
   ggtitle('How engine size relates its highway mileage')

也可以全部寫在一起:labs(x = ' ', y = ' ', title = ' ')

p1 + geom_point(alpha = 1/5) +
   labs(x = 'Engine displacement (L)',
        y = 'Highway mileage (miles/gallon)',
        title = 'How engine size relates its highway mileage')



我們也可以設定 variable 裡面各個觀察的顏色,例如在這個例子裡,我們加入 year 這個變項,然後用顏色區分。

若要加入年份這個 variable,需要在 geom_point 裡面加入:aes(colour = factor(year)

這個指令也可以加在 p1 那層裡面,在這邊為求方便和易理解,所以加在後面。(細節解釋請看這篇這篇

p1 + geom_point(aes(colour = factor(year))) +
     labs(x = 'Engine displacement (L)',
          y = 'Highway mileage (miles/gallon)',
          title = 'How engine size relates its highway mileage')



如果想指定這個年份的顏色,可以用下面的語法設定你要的顏色,也可以設定旁邊圖標(figure legend)的名稱,例如把 factor(year) 改為 Year。

scale_colour_manual(name = " ", values = c(" ", " "))

在名字的地方打入你想要的名稱,在 values = c(" ", " ") 的地方打入你要的顏色。

p1 + geom_point(aes(colour = factor(year))) +
     labs(x = 'Engine displacement (L)',
          y = 'Highway mileage (miles/gallon)',
          title = 'How engine size relates its highway mileage') +
     scale_colour_manual(name = "Year",
                         values = c("light green", "skyblue"))



除此之外,你也可以讓圖標只顯示出你要的觀察,例如說只顯示 2008 年的,並且把它改名為 To Date。

只想顯示某個觀察用:bearks = 
把那個觀察改名用:labels = " "

ggplot(mpg, aes(hwy, cty, colour = factor(year))) +
   geom_point() +
   scale_colour_manual(name = "Year",
                       values = c("light green", "skyblue"),
                       breaks = 2008, labels = "To Date"))



也可以改變圖標的位置,用 theme() 功能裡的 legend.position。

語法是:theme(legend.position = )

p1 + geom_point(aes(colour = factor(year))) +
     labs(x = 'Engine displacement (L)',
          y = 'Highway mileage (miles/gallon)',
          title = 'How engine size relates its highway mileage') +
     scale_colour_manual(name = "Year",
                         values = c("light green""skyblue")) +
     theme(legend.position = 'top')



如果不要圖標,就寫 none:theme(legend.position="none")

如果要更細部的挑整圖標,可以用 guides() 的功能。

對應前面的 colour = factor(year)guides() 功能裡面用的是 colour = guide_legend()。可以在 guide_legend() 裡面設定圖標的標題、位置和格式。

設定標題的話就是直接在 guide_legend() 裡面輸入 "title" (title = 你想要的標題)。

設定位置則是用:label.position = 

也可以把圖標設成兩欄的格式:ncol = 

p1 + geom_point(aes(colour = factor(year))) +
     labs(x = 'Engine displacement (L)',
          y = 'Highway mileage (miles/gallon)',
          title = 'How engine size relates its highway mileage') +
   guides(colour = guide_legend("Year",
                   label.position = "bottom", ncol = 2))



有從上面的圖中看出哪個語法是對應到哪個變化嗎?

接下來,我們用檔案資料 diamonds 來做其他改變。

在之前這一篇有畫過這個圖:

ggplot(diamonds, aes(carat, price)) +
                 geom_point(alpha = 1/15)



可以在其中加入另一個變項 cut,用顏色區分。

ggplot(diamonds, aes(carat, price, colour = cut)) +
                 geom_point(alpha = 1/15)



因為點太多,我們可以隨機挑出兩百個點做試驗,並把圖設為 d1。

隨機挑數的語法是:sample_n(dataframe, #)

d1 <- ggplot(sample_n(diamonds, 200),
      aes(carat, price, colour = cut)) + geom_point()



上面的圖的 Y-axis 間隔都是相同的,我們可以把它改成倍數,也就是用 log 或是 log10。

要改軸的格式可以用上面介紹的 scale_x_continuous()scale_y_continuous()

在這兩個功能裡面可以設軸名、軸的格式、最大值和最小值,還有顯示哪幾個值。

設軸名:name = " " 

設軸上各點的名字:label = c(" ", " ", " ", ...)

例如 X-axis 的標示是 2, 4, 6 的話,可以用 label = c("two", "four", "six") 這個語法改成 two, four, six。

軸的格式可以設成倍數,也就是從原本的 1, 2, 3, .... etc. 轉換成 1, 2, 4, 8, 16, ... etc,用的語法為:trans = "log" 或是 trans = "log10"

最大值和最小值:limits = c(min, max)
也可以用之前介紹過的:xlim(min, max)

只顯示某幾個值:breaks = c(x, y, z, ....)

顯示副軸(minor scale):minor_breaks = (如果沒設的話就是 default 會出現,如果不想要就設 minor_breaks = NULL。)

接下來直接用上面的圖做變化,為了清楚表現以上幾個功能,先從最少的語法開始。下面是

d1 + scale_x_continuous(name = "Carat", limits = c(0.2, 4),
                        breaks = c(0.25, 0.5, 1, 2, 4),
                        minor_breaks = NULL) +
     scale_y_continuous(name = "Price",
                        breaks = 1000 * c(0.5, 1, 2, 4, 8, 16),
                        minor_breaks = NULL)



跟上面的比較,可以看出軸名改了,成為:Price 和 Carat。圖的橫軸變成從 0.2 到 4,軸的點為指定的那四點,各點間依比例設距離,因此畫出來會是 log 的圖。圖的直軸也只顯示設的那幾個點,數字間的距離也是依比例畫的。兩軸皆沒有副軸。

再來加入副軸,也就是把 minor_breaks = NULL 拿掉。然後讓顯示的點都為等距,也就是用 trans = "log" 的功能來畫 log 的圖。

d1 + scale_x_continuous(name = "Carat", limits = c(0.2, 4),
                        trans = "log",
                        breaks = c(0.25, 0.5, 1, 2, 4)) +
     scale_y_continuous(name = "Price", trans = "log10",
                        breaks = 1000 * c(0.5, 1, 2, 4, 8, 16)



再來,我們可以改變圖標的名稱,用的語法是:scale_colour_discrete()

d1 + scale_x_continuous(name = "Carat", limits = c(0.2, 4),
                        trans = "log",
                        breaks = c(0.250.5, 1, 2, 4)) +
     scale_y_continuous(name = "Price", trans = "log10",
                        breaks = 1000 * c(0.5, 1, 2, 4, 8, 16)
     scale_colour_discrete("Cut")



可以看到右邊圖標的名稱改了,如果想要改裡面各個小標的名稱的話,就在功能裡面加:labels = c(" ", " ", " ", ...)


最後,我們用檔案 msleep 來做個練習吧。


Exercise

1. Using the msleep data frame, plot the length of the sleep cycle versus the total amount of sleep. Indicate the animal’s diet by colour. Add appropriate labels to the axes and colour legend, and make the colour key labels more reader-friendly.

ggplot(msleep, aes(sleep_total, sleep_cycle, colour = vore)) +             geom_point() +
       labs(x = "Total sleep (h)",
            y = "Length of sleep cycle",
            title = "Animal Sleep") +
       scale_colour_discrete("Animal Diet",
       labels = c("carnivore", "herbivore",

                  "insectivore", "omnivore", "N/A"))



2. Using the msleep data frame, plot the body weight vs. the brain weight. Indicate the animal’s diet by colour. Add appropriate labels to the axes and colour legend. (Use a log axis if warranted.)

這邊我們會用另一個顏色的功能嘗試:scale_colour_brewer()

用法跟上面的很像,一樣是可以在裡面設定圖標名稱,另外就是這個是調色盤,也可以設定不同的色調,用的語法是:palette = " "

另外,上面介紹的 scale_x_continuous(trans = "log10")scale_y_continuous(trans = "log10") 也可以用較短的 scale_x_log10()scale_y_log10() 代替。

ggplot(msleep, aes(brainwt, bodywt, colour = vore)) +
       geom_point() +
       labs(x = "Brain Weight (kg)",
            y = "Body Weight (kg)",
            title = "Animal Weight") +
       scale_x_log10() + scale_y_log10() +
       scale_colour_brewer("Diet")



如果沒有設定色調的話,預設是藍色。如果想用其他色調的話,可以參考這裡,下面用的是 "Set2"。

ggplot(msleep, aes(brainwt, bodywt, colour = vore)) +
       geom_point() +
       labs(x = "Brain Weight (kg)",
            y = "Body Weight (kg)",
            title = "Animal Weight") +
       scale_x_log10() + scale_y_log10() +
       scale_colour_brewer("Diet", palette = "Set2")



3. Same as Exercise 2, but use the species name instead of a point. Add appropriate labels to the axes and colour legend. (Use a log axis if warranted.)

這邊要把點改成動物名稱,也就是用字去顯示每個點,用的功能是:geom_text()

因為我們要用動物名稱去標示每個點,所以要加入這個指令:label = name

ggplot(msleep, aes(brainwt, bodywt, colour = vore)) +
       geom_text(aes(label = name)) +
       labs(x = "Brain Weight (kg)",
            y = "Body Weight (kg)",
            title = "Animal Weight") +
       scale_x_log10() + scale_y_log10() +
       scale_color_discrete("Diet")




好了,主要的幾個功能大概都介紹了,這篇就先到這邊吧。(總算把這篇打完惹)










2017年12月23日 星期六

R | Data manipulation (2): arrange, mutate, summarise

這篇介紹另外幾個處理資料的功能,上篇請看這裡:R | Data manipulation (1): select, filter, slice

詳細功能介紹請參考這兩頁:Working with Data - Part 1 & Intro to R - Part 3

練習的部分可以參考 slides: Working with Data - Part 1 (pdf)

這幾個功能在 dplyr 這個 package 裡面,所以要先跑。同時要用內建檔案 mtcars 來練習,所以也要叫出來。下面還會用檔案資料 flights,因為它在 nycflights13 這個 packages 裡面,所以也需要安裝。

library(dplyr)
library(nycflights13)
mtcars
flights

下面先介紹一個觀看檔案的功能。

Glimpse function: columns run down the page, and data runs across, making it possible to see every column in a data frame

glimpse() 和平常看檔案的方式不一樣。我們平常看檔案的時候,variables 是在第一列(rows),每個欄位(column)是一個 variables。但用 glimpse() 的話,它會橫向顯示每個 variable 的數據值。

下面先用資料檔案 flights 練習。

dim(flights)

dim: 顯示檔案資料的大小 dimension (row x column)

[1] 336776     19

上面顯示的結果告訴我們,共有 336776 個班機(observations),且用 19 個 variables 呈現各個班機的資訊。

glimpse(flights)

Observations: 336,776
Variables: 19
$ year           <int> 2013, 2013, 2013, 2013, 2013, 2013, ...
$ month          <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ day            <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ dep_time       <int> 517, 533, 542, 544, 554, 554, 555, ...

上面用 glimpse() 功能可以看到每班飛機的資訊(variables)包括有 year, month, day, dep_time 等等。

5. Arrange function: order observations (rows)

沒特別指令的話會由小到大排列。

Default setting: order mpg values from small to large. (依 mpg 的大小排列)

arrange(mtcars, mpg)

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
2  10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
3  13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
4  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
5  14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4

如果要由大到小排列的話,則用:desc()

Use desc() to sort in descending order.
Order mpg from large to small.

arrange(mtcars, desc(mpg))

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
2  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
3  30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
4  30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
5  27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1

如果有兩個 variables 的話,會先排第一個,然後再在第一個裡面排第二個的大小順序。

mtcars %>%
   arrange(cyl, gear)

Arrange with cyl first; then within cyl, arrange gear.

上面的例子中,會先依照 cyl 的大小排列,再依 gear 的大小排列。

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
2  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
3  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
4  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
5  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1

如果想讓兩個 variables 都由大到小排列,可以分開寫,也可以合在一起。

Reorder the mtcars in descending order of mpg and displacement (disp)

mtcars %>%
  arrange(desc(carb), desc(mpg))

或寫成這樣:

mtcars %>%
  arrange(desc(carb, mpg))

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
2  19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
3  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
4  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
5  19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
6  17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4

從上面可以看到是先依 carb 的大小排列,之後再依 mpg 的大小排列(最後四排當 carb 都是 4 的時候,mpg 是由大到小排列),但兩個都是由大到小。

Exercise

這邊我們用檔案資料 flights 來練習。

Q1. Which flights are the most delayed?

哪個班機起飛時間延遲最多,可以用 desc() 由大到小排列延遲的長度,第一個就是延遲最多的。下面先用 glimpse 呈現結果。

flights %>%
  arrange(desc(dep_delay)) %>%
  glimpse

Observations: 336,776
Variables: 19
$ year           <int> 2013, 2013, 2013, 2013, 2013, ...
$ month          <int> 1, 6, 1, 9, 7, 4, 3, 6, 7, 12, 5, 1, 2, ...
$ day            <int> 9, 15, 10, 20, 22, 10, 17, 27, 22, ...
$ dep_time       <int> 641, 1432, 1121, 1139, 845, 1100, 2321, ...
$ sched_dep_time <int> 900, 1935, 1635, 1845, 1600, 1900, 810, ...
$ dep_delay      <dbl> 1301, 1137, 1126, 1014, 1005, 960, ...

從上面顯示的最後一行 dep_delay 可以看到是由大到小排列。

如果不確定哪個 variable 是指延遲時間的話,可以用 help() 的功能來查看:?flights 或是 help(flights)

會在 R Studio 右下角的視窗中出現解釋框(如下圖,點圖可以放大),裡面寫:

dep_delay, arr_delay:
Departure and arrival delays, in minutes. Negative times represent early departures/arrivals.



下面是沒用 glimpse() 功能呈現,應該會比較清楚。

arrange(flights, desc(dep_delay))

# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
 1  2013     1     9      641            900      1301     1242
 2  2013     6    15     1432           1935      1137     1607
 3  2013     1    10     1121           1635      1126     1239
 4  2013     9    20     1139           1845      1014     1457
 5  2013     7    22      845           1600      1005     1044
 6  2013     4    10     1100           1900       960     1342
 7  2013     3    17     2321            810       911      135
 8  2013     6    27      959           1900       899     1236
 9  2013     7    22     2257            759       898      121
10  2013    12     5      756           1700       896     1058
# ... with 336,766 more rows, and 11 more variables:
#   carrier &arr_delay <dbl>,lt;chr>, flight <int>, tailnum <chr>,
#   origin <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

Q2: Which flights caught up the most time during the flight?

哪班飛機趕上的時間最多,就是說即便是延遲起飛,但是仍然準時抵達的,也就是延遲時間最短的(比預計的飛行時間短),這邊用延遲起飛的時間減掉延遲抵達的時間,再由大到小排列。

flights %>%
  arrange(desc(dep_delay - arr_delay)) %>%
  glimpse

Observations: 336,776
Variables: 19
$ year           <int> 2013, 2013, 2013, 2013, 2013, 2013, ...
$ month          <int> 6, 2, 2, 5, 2, 7, 7, 12, 5, 11, 5, 5, ...
$ day            <int> 13, 26, 23, 13, 27, 14, 17, 27, 2, 13, ...
$ dep_time       <int> 1907, 1000, 1226, 1917, 924, 1917, ...
$ sched_dep_time <int> 1512, 900, 900, 1900, 900, 1829, 1930, ...

不用 glimpse 顯示:

arrange(flights, desc(dep_delay - arr_delay))

# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
 1  2013     6    13     1907           1512       235     2134
 2  2013     2    26     1000            900        60     1513
 3  2013     2    23     1226            900       206     1746
 4  2013     5    13     1917           1900        17     2149
 5  2013     2    27      924            900        24     1448
 6  2013     7    14     1917           1829        48     2109
 7  2013     7    17     2004           1930        34     2224
 8  2013    12    27     1719           1648        31     1956
 9  2013     5     2     1947           1949        -2     2209
10  2013    11    13     2024           2015         9     2251
# ... with 336,766 more rows, and 11 more variables:
#   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

可以指定 catchup 為 flights,再帶入 arrange,或是用 head 只顯示前十個 carrier。

flights %>%
  arrange(desc(dep_delay - arr_delay))
head(catchup$carrier, 10)

[1] "EV" "HA" "HA" "DL" "HA" "UA" "UA" "UA" "UA" "DL"

如果只看資料的前十個的話,則是下面這樣。

head(flights$carrier, 10)

[1] "UA" "UA" "AA" "B6" "DL" "UA" "B6" "EV" "B6" "AA"


6. Mutate function: 設定新的 variable,新設定的 variable 會顯示在最後一欄。

Make new variables: disp_l and wt_kg

1L = 61.0237 cu.in. (cubic inch)
1kg = 2.2 lbs

檔案資料裡面的 disp 單位是 cu.in.,我們把它轉換成 L,設定其為 disp_l。同時也把裡面原本單位為磅(lbs)的 wt 換算成 kg,指定其為 wt_kg。新訂的 disp_l 和 wt_kg 會顯示在最後兩的 column。

mtcars %>%
 mutate(disp_l = disp/61.0237,
        wt_kg = wt/2.2)

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb   disp_l     wt_kg
1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 2.621932 1.1909091
2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 2.621932 1.3068182
3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 1.769804 1.0545455
4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 4.227866 1.4613636
5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 5.899347 1.5636364

把重量換算成噸,指定其為:wt_tonnes
Include a variable for weight in tonnes (1t = 2,204.6 lbs)

mtcars %>%
  mutate(wt_tones = wt / 2.2046)

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb  wt_tones
1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 1.1884242
2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 1.3040914
3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 1.0523451
4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 1.4583144
5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 1.5603738


transmute: leave only the new variables

如果用 transmute() 的話,就只會顯示新訂的 disp_1 和 wt_kg。

mtcars %>%
  transmute(disp_l = disp/61.0237, wt_kg = wt/2.2)

     disp_l     wt_kg
1  2.621932 1.1909091
2  2.621932 1.3068182
3  1.769804 1.0545455
4  4.227866 1.4613636
5  5.899347 1.5636364
6  3.687092 1.5727273

Exercise

Q1. Compute speed in mph from time (in minutes) and distance (in miles)

同樣可以用 ?flights 查詢:

distance: Distance between airports, in miles
air_time: Amount of time spent in the air, in minutes

計算飛機的速度:mph = miles per hour

也就是飛行的距離 distance (in miles) 除以飛行的時間 air_time (in minutes)。

因為 air_time 是以分鐘為單位,所以我們必須先把它轉換成小時,也就是:air_time / 60

下面把速度指定為 speed

mutate(flights, speed = distance / (air_time / 60))

# A tibble: 336,776 x 20
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
 1  2013     1     1      517            515         2      830
 2  2013     1     1      533            529         4      850
 3  2013     1     1      542            540         2      923
 4  2013     1     1      544            545        -1     1004
 5  2013     1     1      554            600        -6      812
 6  2013     1     1      554            558        -4      740
 7  2013     1     1      555            600        -5      913
 8  2013     1     1      557            600        -3      709
 9  2013     1     1      557            600        -3      838
10  2013     1     1      558            600        -2      753
# ... with 336,766 more rows, and 12 more variables:
#   arr_delay <dbl>, carrier <chr> flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>,  distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, speed <dbl>

顯示整個檔案太長,看不到後面計算出來的 speed,所以用 select() 的功能挑出我們想看的幾個 variables。如果忘記 select() 是什麼、怎麼用的話,可以看前一篇

mutate(flights, speed = distance / (air_time / 60)) %>%
  select(carrier, distance, air_time, speed)

# A tibble: 336,776 x 4
   carrier distance air_time    speed
     <chr>    <dbl>    <dbl>    <dbl>
 1      UA     1400      227 370.0441
 2      UA     1416      227 374.2731
 3      AA     1089      160 408.3750
 4      B6     1576      183 516.7213
 5      DL      762      116 394.1379
 6      UA      719      150 287.6000
 7      B6     1065      158 404.4304
 8      EV      229       53 259.2453
 9      B6      944      140 404.5714
10      AA      733      138 318.6957
# ... with 336,766 more rows

Q2. Which flight flew the fastest?

哪個班機的速度最快?可以用 arrange() 功能由大到小排列出來,跟上面一樣只挑出我們想看的幾個 variables 來看。

flights %>%
  mutate(speed = distance / (air_time / 60)) %>%
  arrange(desc(speed)) %>%
  select(carrier, distance, air_time, speed)

# A tibble: 336,776 x 4
   carrier distance air_time    speed
     <chr>    <dbl>    <dbl>    <dbl>
 1      DL      762       65 703.3846
 2      EV     1008       93 650.3226
 3      EV      594       55 648.0000
 4      EV      748       70 641.1429
 5      DL     1035      105 591.4286
 6      DL     1598      170 564.0000
 7      B6     1598      172 557.4419
 8      AA     1623      175 556.4571
 9      DL     1598      173 554.2197
10      B6     1598      173 554.2197
# ... with 336,766 more rows

Q3. 把上面班機延遲練習的 Q2,用 select() 的功能挑出我們想看的幾項出來。

flights %>%
  mutate(delay_time = dep_delay - arr_delay) %>%
  arrange(desc(delay_time)) %>%
  select(carrier, dep_time, arr_time, air_time,
         dep_delay, arr_delay, delay_time)

# A tibble: 336,776 x 7
   carrier dep_time arr_time air_time dep_delay arr_delay delay_time
     <chr>    <int>    <int>    <dbl>     <dbl>     <dbl>      <dbl>
 1      EV     1907     2134      126       235       126        109
 2      HA     1000     1513      584        60       -27         87
 3      HA     1226     1746      599       206       126         80
 4      DL     1917     2149      313        17       -62         79
 5      HA      924     1448      589        24       -52         76
 6      UA     1917     2109      274        48       -26         74
 7      UA     2004     2224      295        34       -40         74
 8      UA     1719     1956      324        31       -42         73
 9      UA     1947     2209      300        -2       -75         73
10      DL     2024     2251      311         9       -63         72
# ... with 336,766 more rows

可以和上面排列前十的 carrier 的結果比對,看排列是不是一樣的。


7. Summarise / Summarize

功能和 mutate() 有點像,不一樣的是它會產生一個新的 data frame,並且是那欄(也就是那個 variable)所有觀察資料的總結。

Summarise works in an analogous way to mutate, except instead of adding columns to an existing data frame, it creates a new data frame. This is particularly useful in conjunction with ddply as it makes it easy to perform group-wise summaries.

例如算出 mpg 的平均值,可以用 mean() 的功能這樣算:

mean(mtcars$mpg)

[1] 20.09062

如果用 mutate() 的話會是這樣:

mutate(mtcars, mean(mpg))

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb mean(mpg)
1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4  20.09062
2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4  20.09062
3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1  20.09062
4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1  20.09062
5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2  20.09062

同樣是算出 mean,但它會放在最後一欄,所以所有數值都一樣,因為它是全部觀察算出來的平均值。

如果用 summarise() 的話則是這樣,以一個 data frame 的樣式呈現出來:

summarise(mtcars, mean(mpg))

  mean(mpg)
1  20.09062

也可以幫平均值指定一個名稱 mpg_mean,直接寫在裡面即可。

summarise(mtcars, mpg_mean = mean(mpg)

  mpg_mean
1 20.09062

也可以設定三個,例如把 mpg 的平均值設為 mean_mpg,把重量的中間值設為 median_wt,然後把這兩者的比例設為 ratio

找出中間值用的功能是:median()

mtcars %>%
  summarise(mean_mpg = mean(mpg),
            median_wt = median(wt),
            ratio = mean_mpg/median_wt)

  mean_mpg median_wt    ratio
1 20.09062     3.325 6.042293

也可以全部寫在一行,下面同時把 mpg 的平均值直接設為 mpg,wt 的中間值設為 wt,把兩者的比例設為 ratio

summarise(mtcars, mpg = mean(mpg),
                  wt = median(wt),
                  ratio = mpg/wt)

       mpg    wt    ratio
1 20.09062 3.325 6.042293

除了算全部的平均值外,也可以分組算,例如算出 cyl 裡各種觀察值的平均值。下面先用 levels() 看 cyl 裡面有哪幾種,因為 cyl 的觀察值是數字,需要先把它換成 factor。

levels(factor(mtcars$cyl))

[1] "4" "6" "8"

由上面結果可以看出 cyl 的觀察值有三種:4, 6, 8。如果要看各個的 mpg 和重量平均值,可以用 group_by() 的功能。

mtcars %>%
  group_by(cyl) %>% 
  summarise(mean_mpg = mean(mpg), median_wt = median(wt))

# A tibble: 3 x 3
    cyl mean_mpg median_wt
  <dbl>    <dbl>     <dbl>
1     4 26.66364     2.200
2     6 19.74286     3.215
3     8 15.10000     3.755

也可以在一組裡面再分組算平均值,例如先用 am 分組後,在再裡面用 cyl 分組,先分的那個放前面,所以語法會是:group_by(am, cyl)

mtcars %>%
  group_by(am, cyl) %>%
  summarise(mpg = mean(mpg), wt = median(wt))

# A tibble: 6 x 4
# Groups:   am [?]
     am   cyl      mpg     wt
  <dbl> <dbl>    <dbl>  <dbl>
1     0     4 22.90000 3.1500
2     0     6 19.12500 3.4400
3     0     8 15.05000 3.8100
4     1     4 28.07500 2.0375
5     1     6 20.56667 2.7700
6     1     8 15.40000 3.3700

因為用 summarise() 算出來的結果本身就會轉換成一個 data frame,所以可以把這個 data frame 指定一個名稱,例如為 cars_am_cyl,這樣之後想要看的時候便不需要打全部的語法,只要叫出 cars_am_cyl 即可看。

cars_am_cyl <- mtcars %>%
  group_by(am, cyl) %>%
  summarise(mpg = mean(mpg), wt = median(wt))

cars_am_cyl

因為 cars_am_cyl 已經是一個 data frame,也可以直接用它來做運算,因為上面設定時已經先用 am 分好組了,所以算平均值的時候會依這個分。

cars_am_cyl %>%
  summarise(mpg = mean(mpg), wt = median(wt))

# A tibble: 2 x
     am      mpg    wt
  <dbl>    <dbl> <dbl>
1     0 19.02500  3.44
2     1 21.34722  2.77

也可以相反設試試看,先用 cyl 分組後再依 am 分組運算,也就是 group_by(cyl, am),然後和上面比較有何不同。

cars_cyl_am <- mtcars %>%
  group_by(cyl, am) %>%
  summarise(mpg = mean(mpg), wt = median(wt))

cars_cyl_am

# A tibble: 6 x 4
# Groups:   cyl [?]
    cyl    am      mpg     wt
  <dbl> <dbl>    <dbl>  <dbl>
1     4     0 22.90000 3.1500
2     4     1 28.07500 2.0375
3     6     0 19.12500 3.4400
4     6     1 20.56667 2.7700
5     8     0 15.05000 3.8100
6     8     1 15.40000 3.3700

因為上面是先用 cyl 分組,所以接下來用 cars_cyl_am 來做運算的話,會算出 cyl 裡各組的平均值。

cars_cyl_am %>%
  summarise(mpg = mean(mpg), wt = median(wt))

# A tibble: 3 x 3
    cyl      mpg      wt
  <dbl>    <dbl>   <dbl>
1     4 25.48750 2.59375
2     6 19.84583 3.10500
3     8 15.22500 3.59000

Exercise

Q1. Compute the minimum and maximum displacement for each engine type (vs) by transmission type (am)

在各個引擎的種類中依 am 分組後,找出其中的最大值和最小值,因此要先依引擎分類,再在其中依 am 分組,也就是:group_by(vs, am)

最大值和最小值的功能為:max()min()

mtcars %>%
  group_by(vs, am) %>%
  summarise(min = min(disp), max = max(disp))

# A tibble: 4 x 4
# Groups:   vs [?]
     vs    am   min   max
  <dbl> <dbl> <dbl> <dbl>
1     0     0 275.8   472
2     0     1 120.3   351
3     1     0 120.1   258
4     1     1  71.1   121

Q2. Which destinations have the highest average delays?

flights %>%
  group_by(dest) %>%
  summarise(avg_delay = mean(arr_delay, na.rm = TRUE)) %>%
  arrange(desc(avg_delay))

# A tibble: 105 x 2
    dest avg_delay
   <chr>     <dbl>
 1   CAE  41.76415
 2   TUL  33.65986
 3   OKC  30.61905
 4   JAC  28.09524
 5   TYS  24.06920
 6   MSN  20.19604
 7   RIC  20.11125
 8   CAK  19.69834
 9   DSM  19.00574
10   GRR  18.18956
# ... with 95 more rows


8. Boxplot

接下來試著畫箱圖,如果想畫出在 cyl < 8 的資料中,mpg 對 cyl 的反應,也就是:

x-axis: cyl < 8
y-axis: mpg, response to cyl

boxplot 的語法是:boxplot(formula, data = )

formula 是指兩軸(也就是兩個 variables)的關係,在這裡是: y ~ x 

表示 Y-axis 對 X-axis 的反應,所以也就是:boxplot(y ~ x, data = )

最後用 subset =  的功能挑出你要的,在這個例子裡就是 cyl < 8

boxplot(mpg ~ cyl, data = mtcars, subset= cyl < 8)



也可以用 %>% 分開寫。

You can use . as a placeholder when the “data” argument is in the second position.

mtcars %>%
  filter(cyl < 8) %>%
  boxplot(mpg ~ cyl, data = . )

在上面的語法裡,當前面已經表示過用的資料是 mtcars 的時候,後面在 boxplot() 裡面 data 的部分就可以用 "." 替代,也就是:data = . 

也可以用 ggplot2 來畫圖,用 ggplot 裡的 geom_boxplot() 畫的話,語法就是這樣:

ggplot(mtcars %>%
         filter(cyl < 8), aes(factor(cyl), mpg)) +
  geom_boxplot()

因為 cyl 是數字,所以要需要先把它變成 factor,想更了解的話可以參考這篇:R | ggplot: Point plot & Box plot

也可以先把畫圖要用的資料用 subset() 的功能挑出來,也就是 cyl < 8 的部分。我們可以把挑出來的部分指定成一個新的 data frame,下面我們把指定其為 cyl_sub,然後再用它來畫圖。

cyl_sub <- subset(mtcars, cyl < 8)

ggplot(cyl_sub, aes(factor(cyl), mpg)) + geom_boxplot()



好了,這篇就先到這吧。