下篇會介紹:arrange, mutate, summarise
詳細功能介紹請參考這兩頁: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 |
先介紹定義功能,幾個 operators 可看這篇。
下面先指定 a = 6,然後問 a 是否為 7。
a <- 6 a == 7 |
[1] FALSE |
a 不是 7,所以顯示出來為 FALSE。
如果問:a 不是 7 呢?
a!= 7 |
[1] TRUE |
a 是六不是七是對的,所以顯示為 TRUE。
1. Select function: view only some variables
這是只選某些 variables 出來看,語法是:select(dataframe, var)
只選 mpg 和 wt 這兩項出來看。
select(mtcars, mpg, wt) |
mpg wt Mazda RX4 21.0 2.620 Mazda RX4 Wag 21.0 2.875 Datsun 710 22.8 2.320 Hornet 4 Drive 21.4 3.215 Hornet Sportabout 18.7 3.44 Valiant 18.1 3.460 Duster 360 14.3 3.570 Merc 240D 24.4 3.190 Merc 230 22.8 3.150 Merc 280 19.2 3.440 Merc 280C 17.8 3.440 ...... |
選出 variables 開頭是 "d" 的。
select(mtcars, starts_with("d")) |
disp drat Mazda RX4 160.0 3.90 Mazda RX4 Wag 160.0 3.90 Datsun 710 108.0 3.85 Hornet 4 Drive 258.0 3.08 Hornet Sportabout 360.0 3.15 Valiant 225.0 2.76 Duster 360 360.0 3.21 ...... |
列出所有的 variables。
select(mtcars, everything()) |
2. Filter function: choose observations by their values
和 select() 不同的是 filter() 挑的更進一步,是選出某個 variable 裡的某個觀察(observations),例如下面是選出 cyl 這個 variable 裡面,數值為 8 的那些。
filter(mtcars, cyl == 8) |
mpg cyl disp hp drat wt qsec vs am gear carb 1 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 2 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 3 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 4 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 5 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3 6 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4 ...... |
找出小於八的。
filter(mtcars, cyl < 8) |
加兩個條件,用「或」(or),指令符號是: |
例如下面是找出 cyl 是 4 或 8 的。
filter(mtcars, cyl == 4 | cyl == 8) |
mpg cyl disp hp drat wt qsec vs am gear carb 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 2 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 3 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 4 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 5 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 6 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 ...... |
在上面的例子中,因為我們想找的是在 cyl 中符合 4 和 8 的條件的,因此我們也可以用 %in% 的語法:var %in% c(obs1, obs2)
這是指在某個 variable 中找出裡面符合觀察值(obs)為特定值的項目,不一定要兩個,可以只有一個,也可以兩個以上,看你想找什麼,用上面的例子就會是:cyl %in% c(4, 8)
filter(mtcars, cyl %in% c(4, 8)) |
找出同時符合兩個條件的,用「和」(and),指令符號是: &
例如下面是找出 cyl 和 carb 都是八的。
filter(mtcars, cyl == 8 & carb == 8) |
mpg cyl disp hp drat wt qsec vs am gear carb 1 15 8 301 335 3.54 3.57 14.6 0 1 5 8 |
用上面的語法前面只會出現數字,如果要顯示出是每列的名稱(也就是哪種車),可以用下面的語法。
mtcars[mtcars$cyl == 4 | mtcars$carb == 8, ] |
mpg cyl disp hp drat wt qsec vs am gear carb Maserati Bora 15 8 301 335 3.54 3.57 14.6 0 1 5 8 |
select() 是挑出你想看的 variables,那如果想看某種特定條件下 variables 裡面的觀察值呢?例如我想看 variable qsec,但不想看全部的,只想看 cyl = 8 下的 qsec 值是什麼,這時候可以分開設,先用 filter() 找出 cyl = 8 的,然後再用 select() 看裡面的 qsec。
df <- filter(mtcars, cyl == 8) select(df, qsec) |
qsec 1 17.02 2 15.84 3 17.40 4 17.60 5 18.00 6 17.98 7 17.82 8 17.42 9 16.87 10 17.30 11 15.41 12 17.05 13 14.50 14 14.60 |
3. Slice function
和上面 filter() 不同的,slice() 是挑選某幾列(row)出來看,例如前三列或最後一列,而不是挑某種特定條件。
例如你只想要列出第三列的資料,可以這樣:
slice(mtcars, 3L) slice(mtcars, 3) |
上面的兩種語法會出現同樣的結果,如下。
# A tibble: 1 x 11 mpg cyl disp hp drat wt qsec vs am gear carb <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1 |
Note: slice() and filter() do not carry the row names with the subset of rows(注意:filter 和 slice 這兩個功能都不會在表格的前面顯示列的名稱,只有號碼。)
如果你想要列出第 1, 3, 5 列的資料,可以用 c(1, 3, 5)。
slice(mtcars, c(1, 3, 5)) |
# A tibble: 3 x 11 mpg cyl disp hp drat wt qsec vs am gear carb <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 21.0 6 160 110 3.90 2.62 16.46 0 1 4 4 2 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1 3 18.7 8 360 175 3.15 3.44 17.02 0 0 3 2 |
如果你想要顯示最後一行,不用找出一共有幾行,可以用這個語法: n()
n(): the number of observations in the current group.(表示那組有幾個觀察值就是幾個)
把它設在你想要挑選的列值的話,就會顯示最後一列,因為它的值是所有觀察值。例如 mtcars 總共有 32 個觀察值(就是有 32 列),那 n() 就是 32,於是就會顯示出第 32 列。
slice(mtcars, n()) |
# A tibble: 1 x 11 mpg cyl disp hp drat wt qsec vs am gear carb <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2 |
在上面的語法中,slice(mtcars, n()) 其實就是 slice(mtcars, 32),但如果用 n() 的話,就可以套用到所有資料李,不用每次改成最後一列的數字。
也可以用 filter() 的功能顯示最後一列,用的語法是:row_number() == n()
filter(mtcars, row_number() == n()) |
mpg cyl disp hp drat wt qsec vs am gear carb 1 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2 |
同理,如果要顯示從某行到最後一行的話,可以這樣:
slice(mtcars, 5:n()) |
# A tibble: 28 x 11 mpg cyl disp hp drat wt qsec vs am gear carb <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 18.7 8 360.0 175 3.15 3.44 17.02 0 0 3 2 2 18.1 6 225.0 105 2.76 3.46 20.22 1 0 3 1 3 14.3 8 360.0 245 3.21 3.57 15.84 0 0 3 4 4 24.4 4 146.7 62 3.69 3.19 20.00 1 0 4 2 5 22.8 4 140.8 95 3.92 3.15 22.90 1 0 4 2 6 19.2 6 167.6 123 3.92 3.44 18.30 1 0 4 4 7 17.8 6 167.6 123 3.92 3.44 18.90 1 0 4 4 8 16.4 8 275.8 180 3.07 4.07 17.40 0 0 3 3 9 17.3 8 275.8 180 3.07 3.73 17.60 0 0 3 3 10 15.2 8 275.8 180 3.07 3.78 18.00 0 0 3 3 # ... with 18 more rows |
因為 filter() 和 select() 功能都是不會給列名的,只有給數字,我們可以用 add_rownames() 或是 tibble::rownames_to_column() 的功能。
filter(add_rownames(mtcars), cyl == 8, carb == 3) |
# A tibble: 3 x 12 rowname mpg cyl disp hp drat wt qsec vs am gear <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 Merc 450SE 16.4 8 275.8 180 3.07 4.07 17.4 0 0 3 2 Merc 450SL 17.3 8 275.8 180 3.07 3.73 17.6 0 0 3 3 Merc 450SLC 15.2 8 275.8 180 3.07 3.78 18.0 0 0 3 Warning message: Deprecated, use tibble::rownames_to_column() instead. |
filter(tibble::rownames_to_column(mtcars), cyl == 8, carb == 3) |
rowname mpg cyl disp hp drat wt qsec vs am gear carb 1 Merc 450SE 16.4 8 275.8 180 3.07 4.07 17.4 0 0 3 3 2 Merc 450SL 17.3 8 275.8 180 3.07 3.73 17.6 0 0 3 3 3 Merc 450SLC 15.2 8 275.8 180 3.07 3.78 18.0 0 0 3 3 |
在 slice() 的表格裡加 row name 的話就是這樣:(下面顯示第三到五列)
slice(tibble::rownames_to_column(mtcars), c(3:5)) |
# A tibble: 3 x 12 rowname mpg cyl disp hp drat wt qsec vs am <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 2 Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 |
Exercise
Q1. 找出 mtcars 檔案裡面 qsec 和 am 的資料,並把檔案裡第一個 column 的資料(i.e., mpg)指定為 am。
因為是要把 qsec 和 am 這兩個 variables 找出來看,所以用的是 select() 這個功能。
select(mtcars, qsec, am = 1) |
在 select() 的功能裡,如果用 var = # 這個語法,就是指把某個 variable 指定為檔案裡某一行的 variable,例如上面的 am = 1 就是指把 am 指定為檔案裡原本為第一行的 mpg,你可以看到 am 裡出現的的數值其實是 mpg 裡的。
qsec am Mazda RX4 16.46 21.0 Mazda RX4 Wag 17.02 21.0 Datsun 710 18.61 22.8 Hornet 4 Drive 19.44 21.4 Hornet Sportabout 17.02 18.7 |
下面我們用 am = 2,檔案裡的第二欄是 cyl,所以 am 裡的值會變成 cyl 裡的。
select(mtcars, qsec, am = 2) |
qsec am Mazda RX4 16.46 6 Mazda RX4 Wag 17.02 6 Datsun 710 18.61 4 Hornet 4 Drive 19.44 6 Hornet Sportabout 17.02 8 |
Q2. 找出檔案裡 am 是 1 的。
因為是挑處某個 variable 裡面的某個觀察值,所以要用 filter(),和上面不同的地方是要用 ==。
filter(mtcars, am == 1) |
mpg cyl disp hp drat wt qsec vs am gear carb 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 |
Q3. Extract the 1/4 mile time for cars with manual transmissions (找出檔案裡面 am 是 1 的 qsec 值)
am: transmission (0 = automatic, 1 = manual)
qsec: 1/4 mile time
select(filter(mtcars, am == 1), qsec) |
qsec 1 16.46 2 17.02 3 18.61 4 19.47 5 18.52 6 19.90 7 18.90 8 16.70 9 16.90 10 14.50 11 15.50 12 14.60 13 18.60 |
Q4. Extract the mpg & wt for those cars with 5 gears or a manual transmission (找出檔案裡面 am 值是 1 或 gear 值是 5 的 qsec 值)
select(filter(mtcars, gear == 5 | am == 1), mpg, wt) |
mpg wt 1 21.0 2.620 2 21.0 2.875 3 22.8 2.320 4 32.4 2.200 5 30.4 1.615 6 33.9 1.835 7 27.3 1.935 8 26.0 2.140 9 30.4 1.513 10 15.8 3.170 11 19.7 2.770 12 15.0 3.570 13 21.4 2.780 |
4. Piping (%>%): used when combining several function call together the command can be very hard to read
這個功能在 library(dplyr) 裡面,如果你用的疊層太多,很長的話,可以用 piping 把它分層變短。
Note: f(x) %>% g(y) is the same as g(f(x),y)
Exercise 1: Use %>% for Q3(把上面 Q3 的答案用 %>% 寫出來)
select(filter(mtcars, am == 1), qsec) |
上面的是指在 mtcars 裡挑出 am == 1,再從裡面挑出 qsec 的資料。也就是說,mtcars 是最外層的,再來是 am == 1,最後才是 qsec。
mtcars %>% filter(am == 1) %>% select(qsec) |
Exercise 2:
as.data.frame(select(filter(add_rownames(mtcars), mpg >= 30), rowname, mpg, cyl, hp)) |
把上面的語法用 %>% 分句寫。拆開來看是把 mtcars 加了列名之後,挑出 mpg >=30,再從裡面挑出 rowname, mpg cyl, hp 這幾項用 dataframe 的形式呈現出來。
add_rownames(mtcars) %>% filter(mpg >= 30) %>% select(rowname, mpg, cyl, hp) %>% as.data.frame() |
最後,我們用檔案資料 flights 來練習一下。
Q1. Select all flights on January 2, but leave out the date columns.
選出所以一月二號的班機,不用顯示出日期(年月日)的那幾欄。
下面先看一下 flights 長怎樣。
head(flights) |
# A tibble: 6 x 19 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 # ... with 10 more variables: carrier <chr>, flight <int>, # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, # distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm> |
挑出 variables 裡面的某個觀察,要用 filter() 挑出 month == 1 和 day == 2。要挑出某些 variables 的話要用 select(),如果要剔除的話同樣用 select(),但是在不要的 variables 前面加 - 。
flights %>% filter(month == 1, day == 2) %>% select(-year, -month, -day) |
也可以這樣:
flights %>% filter(month == 1, day == 2) %>% select(-(year:day)) |
# A tibble: 943 x 16 dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay <int> <int> <dbl> <int> <int> <dbl> 1 42 2359 43 518 442 36 2 126 2250 156 233 2359 154 3 458 500 -2 703 650 13 4 512 515 -3 809 819 -10 5 535 540 -5 831 850 -19 |
可以看到上面的顯示的結果沒有 year, month 和 day 那三欄。
另外幾個處理檔案資料的功能請看這篇:R | Data manipulation (2): arrange, mutate, summarise
沒有留言:
張貼留言
歡迎發表意見