Các lệnh sắp xếp dữ liệu

Câu 1

Sử dụng dataset df1.rds

https://github.com/tuhocr/homework/blob/main/dataset/df1.rds

Bạn có bộ dữ liệu sau, đây là kết quả đo chỉ số CD3+_T_CELL_FREQ ở hai thời điểm trước và sau. Ta sẽ thấy trong nhóm CONTROL_OLDCONTROL_YOUNG ở cột BEGIN_CD3+_T_CELL_FREQ có đủ dữ liệu, trong khi ở cột FU_CD3+_T_CELL_FREQ tương ứng thì bị thiếu dữ liệu.

df <- readRDS("dataset/df1.rds")

df
   STUDY_ID     STUDY_ARM BEGIN_CD3+_T_CELL_FREQ FU_CD3+_T_CELL_FREQ
1      ID_1   CONTROL_OLD              12.063157                  NA
2      ID_2   CONTROL_OLD              10.964920                  NA
3      ID_3          YEGD               6.135557           15.411331
4      ID_4   CONTROL_OLD              13.720531                  NA
5      ID_5   CONTROL_OLD              10.207501                  NA
6      ID_6   CONTROL_OLD              10.781260                  NA
7      ID_7   CONTROL_OLD               8.561287                  NA
8      ID_8          YEGD              10.378400           36.150698
9      ID_9   CONTROL_OLD              12.419222                  NA
10    ID_10          YEGD               4.698543           53.858413
11    ID_11   CONTROL_OLD               9.877577                  NA
12    ID_12   CONTROL_OLD              11.327839                  NA
13    ID_13          YEGD              10.810302                  NA
14    ID_14          YEGD              12.559336                  NA
15    ID_15   CONTROL_OLD              12.618815                  NA
16    ID_16   CONTROL_OLD               9.354778                  NA
17    ID_17          YEGD               4.883078           30.915139
18    ID_18   CONTROL_OLD              10.481444                  NA
19    ID_19   CONTROL_OLD              10.954867                  NA
20    ID_20          YEGD              10.257006           12.503797
21    ID_21 CONTROL_YOUNG              12.011571                  NA
22    ID_22          YEGD               9.304376           45.202878
23    ID_23 CONTROL_YOUNG              12.267157                  NA
24    ID_24          YEGD               9.591158            8.710753
25    ID_25          YEGD              10.470832           10.584096
26    ID_26          YEGD              12.824044           42.963687
27    ID_27 CONTROL_YOUNG               9.660034                  NA
28    ID_28 CONTROL_YOUNG              12.845677                  NA
29    ID_29   CONTROL_OLD              10.438020                  NA
30    ID_30          YEGD               9.466437           62.817237

Bạn hãy chuyển dữ liệu từ cột BEGIN qua cột FU chỉ dành cho hai nhóm CONTROL_OLDCONTROL_YOUNG, để thu được kết quả như sau, cột mới tạo đặt tên là FU_CD3+_T_CELL_FREQ_new.

   STUDY_ID     STUDY_ARM BEGIN_CD3+_T_CELL_FREQ FU_CD3+_T_CELL_FREQ FU_CD3+_T_CELL_FREQ_new
1      ID_1   CONTROL_OLD              12.063157                  NA               12.063157
2      ID_2   CONTROL_OLD              10.964920                  NA               10.964920
3      ID_3          YEGD               6.135557           15.411331               15.411331
4      ID_4   CONTROL_OLD              13.720531                  NA               13.720531
5      ID_5   CONTROL_OLD              10.207501                  NA               10.207501
6      ID_6   CONTROL_OLD              10.781260                  NA               10.781260
7      ID_7   CONTROL_OLD               8.561287                  NA                8.561287
8      ID_8          YEGD              10.378400           36.150698               36.150698
9      ID_9   CONTROL_OLD              12.419222                  NA               12.419222
10    ID_10          YEGD               4.698543           53.858413               53.858413
11    ID_11   CONTROL_OLD               9.877577                  NA                9.877577
12    ID_12   CONTROL_OLD              11.327839                  NA               11.327839
13    ID_13          YEGD              10.810302                  NA                      NA
14    ID_14          YEGD              12.559336                  NA                      NA
15    ID_15   CONTROL_OLD              12.618815                  NA               12.618815
16    ID_16   CONTROL_OLD               9.354778                  NA                9.354778
17    ID_17          YEGD               4.883078           30.915139               30.915139
18    ID_18   CONTROL_OLD              10.481444                  NA               10.481444
19    ID_19   CONTROL_OLD              10.954867                  NA               10.954867
20    ID_20          YEGD              10.257006           12.503797               12.503797
21    ID_21 CONTROL_YOUNG              12.011571                  NA               12.011571
22    ID_22          YEGD               9.304376           45.202878               45.202878
23    ID_23 CONTROL_YOUNG              12.267157                  NA               12.267157
24    ID_24          YEGD               9.591158            8.710753                8.710753
25    ID_25          YEGD              10.470832           10.584096               10.584096
26    ID_26          YEGD              12.824044           42.963687               42.963687
27    ID_27 CONTROL_YOUNG               9.660034                  NA                9.660034
28    ID_28 CONTROL_YOUNG              12.845677                  NA               12.845677
29    ID_29   CONTROL_OLD              10.438020                  NA               10.438020
30    ID_30          YEGD               9.466437           62.817237               62.817237

Cách 1: Khai báo trực tiếp tên biến

Chú ý nếu tên biến có ký tự đặc biệt thì cần đặt trong hai dấu backticks ``

df <- readRDS("dataset/df1.rds")

library(dplyr)
library(rlang)

df %>% dplyr:::mutate( `FU_CD3+_T_CELL_FREQ_new` = case_when(
  
  STUDY_ARM == "CONTROL_OLD" ~ `BEGIN_CD3+_T_CELL_FREQ`,
  
  STUDY_ARM == "CONTROL_YOUNG" ~ `BEGIN_CD3+_T_CELL_FREQ`,
  
  STUDY_ARM == "YEGD" ~ `FU_CD3+_T_CELL_FREQ`,
  
  .default = NA
  
)) -> df_clean1

df_clean1
   STUDY_ID     STUDY_ARM BEGIN_CD3+_T_CELL_FREQ FU_CD3+_T_CELL_FREQ FU_CD3+_T_CELL_FREQ_new
1      ID_1   CONTROL_OLD              12.063157                  NA               12.063157
2      ID_2   CONTROL_OLD              10.964920                  NA               10.964920
3      ID_3          YEGD               6.135557           15.411331               15.411331
4      ID_4   CONTROL_OLD              13.720531                  NA               13.720531
5      ID_5   CONTROL_OLD              10.207501                  NA               10.207501
6      ID_6   CONTROL_OLD              10.781260                  NA               10.781260
7      ID_7   CONTROL_OLD               8.561287                  NA                8.561287
8      ID_8          YEGD              10.378400           36.150698               36.150698
9      ID_9   CONTROL_OLD              12.419222                  NA               12.419222
10    ID_10          YEGD               4.698543           53.858413               53.858413
11    ID_11   CONTROL_OLD               9.877577                  NA                9.877577
12    ID_12   CONTROL_OLD              11.327839                  NA               11.327839
13    ID_13          YEGD              10.810302                  NA                      NA
14    ID_14          YEGD              12.559336                  NA                      NA
15    ID_15   CONTROL_OLD              12.618815                  NA               12.618815
16    ID_16   CONTROL_OLD               9.354778                  NA                9.354778
17    ID_17          YEGD               4.883078           30.915139               30.915139
18    ID_18   CONTROL_OLD              10.481444                  NA               10.481444
19    ID_19   CONTROL_OLD              10.954867                  NA               10.954867
20    ID_20          YEGD              10.257006           12.503797               12.503797
21    ID_21 CONTROL_YOUNG              12.011571                  NA               12.011571
22    ID_22          YEGD               9.304376           45.202878               45.202878
23    ID_23 CONTROL_YOUNG              12.267157                  NA               12.267157
24    ID_24          YEGD               9.591158            8.710753                8.710753
25    ID_25          YEGD              10.470832           10.584096               10.584096
26    ID_26          YEGD              12.824044           42.963687               42.963687
27    ID_27 CONTROL_YOUNG               9.660034                  NA                9.660034
28    ID_28 CONTROL_YOUNG              12.845677                  NA               12.845677
29    ID_29   CONTROL_OLD              10.438020                  NA               10.438020
30    ID_30          YEGD               9.466437           62.817237               62.817237

Cách 2: Khai báo tên biến theo kiểu truyền tham số

Từ khóa: pass variable in dplyr; dynamic variable/column in dplyr

df <- readRDS("dataset/df1.rds")

v1 <- "BEGIN_CD3+_T_CELL_FREQ"

v2 <- "FU_CD3+_T_CELL_FREQ"

v3 <- "FU_CD3+_T_CELL_FREQ_new"

library(dplyr)
library(rlang)

df %>% dplyr:::mutate( {{ v3 }} := case_when(
  
  STUDY_ARM == "CONTROL_OLD" ~ get(v1),
  
  STUDY_ARM == "CONTROL_YOUNG" ~ get(v1),
  
  STUDY_ARM == "YEGD" ~ get(v2),
  
  .default = NA
  
)) -> df_clean2

df_clean2
   STUDY_ID     STUDY_ARM BEGIN_CD3+_T_CELL_FREQ FU_CD3+_T_CELL_FREQ FU_CD3+_T_CELL_FREQ_new
1      ID_1   CONTROL_OLD              12.063157                  NA               12.063157
2      ID_2   CONTROL_OLD              10.964920                  NA               10.964920
3      ID_3          YEGD               6.135557           15.411331               15.411331
4      ID_4   CONTROL_OLD              13.720531                  NA               13.720531
5      ID_5   CONTROL_OLD              10.207501                  NA               10.207501
6      ID_6   CONTROL_OLD              10.781260                  NA               10.781260
7      ID_7   CONTROL_OLD               8.561287                  NA                8.561287
8      ID_8          YEGD              10.378400           36.150698               36.150698
9      ID_9   CONTROL_OLD              12.419222                  NA               12.419222
10    ID_10          YEGD               4.698543           53.858413               53.858413
11    ID_11   CONTROL_OLD               9.877577                  NA                9.877577
12    ID_12   CONTROL_OLD              11.327839                  NA               11.327839
13    ID_13          YEGD              10.810302                  NA                      NA
14    ID_14          YEGD              12.559336                  NA                      NA
15    ID_15   CONTROL_OLD              12.618815                  NA               12.618815
16    ID_16   CONTROL_OLD               9.354778                  NA                9.354778
17    ID_17          YEGD               4.883078           30.915139               30.915139
18    ID_18   CONTROL_OLD              10.481444                  NA               10.481444
19    ID_19   CONTROL_OLD              10.954867                  NA               10.954867
20    ID_20          YEGD              10.257006           12.503797               12.503797
21    ID_21 CONTROL_YOUNG              12.011571                  NA               12.011571
22    ID_22          YEGD               9.304376           45.202878               45.202878
23    ID_23 CONTROL_YOUNG              12.267157                  NA               12.267157
24    ID_24          YEGD               9.591158            8.710753                8.710753
25    ID_25          YEGD              10.470832           10.584096               10.584096
26    ID_26          YEGD              12.824044           42.963687               42.963687
27    ID_27 CONTROL_YOUNG               9.660034                  NA                9.660034
28    ID_28 CONTROL_YOUNG              12.845677                  NA               12.845677
29    ID_29   CONTROL_OLD              10.438020                  NA               10.438020
30    ID_30          YEGD               9.466437           62.817237               62.817237

Xác nhận kết quả tính bằng hai cách là như nhau

identical(df_clean1, df_clean2)
[1] TRUE

Câu 2

Sử dụng dataset ket_qua_phan_tich_dat_full.xlsx

library(readxl)
df <- read_excel("dataset/ket_qua_phan_tich_dat_full.xlsx",
                 range = "B7:I10")

df <- as.data.frame(df)

df
  TT   location pH-1 pH-2 pH-3 salinity-1 salinity-2 salinity-3
1  1  BÌNH MINH 5.33 5.92  6.1       3.20       2.80       2.90
2  2 CHÂU THÀNH 6.50 7.20  6.8       0.25       0.00       0.01
3  3    ĐỨC HÒA 5.99 5.40  5.7       2.10       1.58       2.00

Bạn hãy chuyển dữ liệu thành dạng true long (mỗi dòng là đại diện cho 1 quan sát duy nhất (1 value), mã ID có thể bị trùng lặp) và dạng semi long (mỗi dòng là có thể có nhiều quan sát trên cùng mã ID, mã ID có thể bị trùng lặp).

Chuyển về dạng true long

library(tidyr)

df_long <- tidyr:::pivot_longer(df, 
                                #vị trí các cột cần rã về dạng long
                                cols = c(3:8),
                                names_to = "chitieu", 
                                values_to = "ketqua")

df_long <- as.data.frame(df_long)

# cần loại bỏ các ký tự -1, -2, -3
df_long
   TT   location    chitieu ketqua
1   1  BÌNH MINH       pH-1   5.33
2   1  BÌNH MINH       pH-2   5.92
3   1  BÌNH MINH       pH-3   6.10
4   1  BÌNH MINH salinity-1   3.20
5   1  BÌNH MINH salinity-2   2.80
6   1  BÌNH MINH salinity-3   2.90
7   2 CHÂU THÀNH       pH-1   6.50
8   2 CHÂU THÀNH       pH-2   7.20
9   2 CHÂU THÀNH       pH-3   6.80
10  2 CHÂU THÀNH salinity-1   0.25
11  2 CHÂU THÀNH salinity-2   0.00
12  2 CHÂU THÀNH salinity-3   0.01
13  3    ĐỨC HÒA       pH-1   5.99
14  3    ĐỨC HÒA       pH-2   5.40
15  3    ĐỨC HÒA       pH-3   5.70
16  3    ĐỨC HÒA salinity-1   2.10
17  3    ĐỨC HÒA salinity-2   1.58
18  3    ĐỨC HÒA salinity-3   2.00
gsub(pattern = "-(1|2|3)",
     replacement = "",
     df_long$chitieu) -> df_long$chitieu

# sắp xếp lại theo thứ tự
df_long |> dplyr:::arrange(chitieu, location) -> df_long
df_long
   TT   location  chitieu ketqua
1   1  BÌNH MINH       pH   5.33
2   1  BÌNH MINH       pH   5.92
3   1  BÌNH MINH       pH   6.10
4   2 CHÂU THÀNH       pH   6.50
5   2 CHÂU THÀNH       pH   7.20
6   2 CHÂU THÀNH       pH   6.80
7   3    ĐỨC HÒA       pH   5.99
8   3    ĐỨC HÒA       pH   5.40
9   3    ĐỨC HÒA       pH   5.70
10  1  BÌNH MINH salinity   3.20
11  1  BÌNH MINH salinity   2.80
12  1  BÌNH MINH salinity   2.90
13  2 CHÂU THÀNH salinity   0.25
14  2 CHÂU THÀNH salinity   0.00
15  2 CHÂU THÀNH salinity   0.01
16  3    ĐỨC HÒA salinity   2.10
17  3    ĐỨC HÒA salinity   1.58
18  3    ĐỨC HÒA salinity   2.00

Chuyển về dạng semi-long

library(splitstackshape)

# ta muốn giữ lại cột `pH` và `salinity`, theo quy tắc separator -1, -2, -3 thì loại đi
names(df)
[1] "TT"         "location"   "pH-1"       "pH-2"       "pH-3"       "salinity-1" "salinity-2" "salinity-3"
df_semi <- splitstackshape:::Reshape(df, 
                                     # cột giữ lại
                                     id.vars = c("TT", "location"),
                                     # cột chuyển qua semi-long
                                     var.stubs = c("pH", "salinity"),
                                     # quy ước gộp cột theo ký tự separator
                                     sep = "-")

df_semi <- as.data.frame(df_semi)

df_semi |> dplyr:::arrange(location, time) -> df_semi

df_semi
  TT   location time   pH salinity
1  1  BÌNH MINH    1 5.33     3.20
2  1  BÌNH MINH    2 5.92     2.80
3  1  BÌNH MINH    3 6.10     2.90
4  2 CHÂU THÀNH    1 6.50     0.25
5  2 CHÂU THÀNH    2 7.20     0.00
6  2 CHÂU THÀNH    3 6.80     0.01
7  3    ĐỨC HÒA    1 5.99     2.10
8  3    ĐỨC HÒA    2 5.40     1.58
9  3    ĐỨC HÒA    3 5.70     2.00

Câu 3

Bạn có dataset dạng long như sau, ta có mỗi mã ID được lặp lại 2 lần.

id <- c("id301", "id301",
        "id302", "id302",
        "id303", "id303",
        "id304", "id304",
        "id305", "id305")

c63 <- c("YES", "NO",
         "YES", NA,
         "NO", "YES",
         NA, NA,
         NA, "YES")

df <- data.frame(id, c63)

df
      id  c63
1  id301  YES
2  id301   NO
3  id302  YES
4  id302 <NA>
5  id303   NO
6  id303  YES
7  id304 <NA>
8  id304 <NA>
9  id305 <NA>
10 id305  YES

Bạn hãy xoay ngang dataset này qua dạng wide để có kết quả như vầy nhé.

     id c63_1 c63_2
1 id301   YES    NO
2 id302   YES  <NA>
3 id303    NO   YES
4 id304  <NA>  <NA>
5 id305  <NA>   YES

Để xoay ngang dữ liệu này, ta cần tạo thêm 1 cột nữa giúp R định vị được khi xoay ngang sẽ căn cứ theo cột đó.

library(dplyr)
library(tidyr)

df_wide <- df  %>%
  group_by(id) %>%
  mutate(c63_no = row_number()) %>% as.data.frame()

df_wide
      id  c63 c63_no
1  id301  YES      1
2  id301   NO      2
3  id302  YES      1
4  id302 <NA>      2
5  id303   NO      1
6  id303  YES      2
7  id304 <NA>      1
8  id304 <NA>      2
9  id305 <NA>      1
10 id305  YES      2

Áp dụng cú pháp reshape để xoay ngang bộ dữ liệu.

df_wide |> pivot_wider(
    id_cols     = id,
    names_from  = c63_no,
    values_from = c63,
    names_prefix = "c63_"
  ) |> as.data.frame() -> df_wide

df_wide
     id c63_1 c63_2
1 id301   YES    NO
2 id302   YES  <NA>
3 id303    NO   YES
4 id304  <NA>  <NA>
5 id305  <NA>   YES