からっぽのしょこ

読んだら書く!書いたら読む!同じ事は二度調べ(たく)ない

5-4:googlesheets4パッケージによるスプレッドシートの読み込み・書き出し時のメモ【R登山本】

はじめに

 『Rが生産性を高める 〜データ分析ワークフロー効率化の実践』(R登山本)の内容を実際にやってみた記録や気になったことのメモです。

 この記事は、5-4節「Googleスプレッドシートの操作」の補足的な内容です。詳しくは本を読んでください。

【前の内容】

www.anarchive-beta.com

【この記事の内容】

5-4 スプレッドシートの読み込みと書き出し

 認証方法などの初期設定やシートの読み込み・書き出し時の細かい設定、スプレッドシート上での操作などについては本を読んでください。

 利用するパッケージを読み込みます。

# 利用するパッケージ
library(googledrive)
library(googlesheets4)
library(palmerpenguins)

 例として使用するファイルの作成にpalmerpenguinsを使います。

スプレッドシートのアップロード

 まずは、Google Dirve上にスプレッドシートをアップロード・作成する方法を確認します。

 例として用いるため、ペンギンデータセットを取得します。

# データセットを取得
penguins_df <- palmerpenguins::penguins
head(penguins_df)
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <fct>   <fct>           <dbl>         <dbl>            <int>       <int> <fct>
## 1 Adelie  Torge~           39.1          18.7              181        3750 male 
## 2 Adelie  Torge~           39.5          17.4              186        3800 fema~
## 3 Adelie  Torge~           40.3          18                195        3250 fema~
## 4 Adelie  Torge~           NA            NA                 NA          NA <NA> 
## 5 Adelie  Torge~           36.7          19.3              193        3450 fema~
## 6 Adelie  Torge~           39.3          20.6              190        3650 male 
## # ... with 1 more variable: year <int>

 palmerpenguinsパッケージのpenguinsデータセットを利用します。

 googledriveパッケージを利用して、スプレッドシートとして書き出します。詳しくは5-3節を参照してください。

# データフレームをローカルに書き出し
readr::write_csv(
  x = penguins_df, 
  file = "data/penguins.csv", 
  na = ""
)

# スプレッドシートとしてアップロード
googledrive::drive_upload(
  media = "data/penguins.csv", 
  path = "tozan_book/chapter5/", 
  name = "penguins", 
  type = "spreadsheet", 
  overwrite = TRUE
)

 readrパッケージのwrite_csv()で、データフレームの内容をcsvファイルとしてローカルに保存します。
 googledriveパッケージのdrive_upload()で、csvファイルの内容をスプレッドシートとしてGoogleドライブに保存します。

 この方法だと、元のファイル名がシート名になります。
 また欠損値NAを含む場合、デフォルトではセルの値が文字列のNAになります。write_csv()na引数に""を指定すると、空白のセルになります。

 または、googlesheets4パッケージを利用して、スプレッドシートを作成します。

# スプレッドシートとしてアップロード
metadata_sheets_id <- googlesheets4::gs4_create(
  name = "penguins", 
  sheets = list(Sheet1 = penguins_df)
)

 googlesheets4パッケージのgs4_create()で、データフレームの内容をスプレッドシートとしてGoogleドライブに保存します。

 この方法だと、デフォルトではシート名が「シート1」になります。sheets引数にリスト形式でlist(シート名 = データフレーム)と指定することで、シート名を指定できます。リストに複数のデータフレームを格納(list(シート1 = データ1, シート2 = データ2))すると、複数のシートを持つスプレッドシートを作成できます。
 name引数に、スプレッドシート名(ファイル名)を指定します。
 欠損値NAは空白セルになります。

 また、ファイルの作成時にシートID(sheets_idオブジェクト)が出力されます。詳しくは次で確認します。

 ただし、アップロード先を指定できないようです(?)。
 そこで、作成したスプレッドシートを移動します。

# ファイルを移動
googledrive::drive_mv(
  file = metadata_sheets_id, 
  path = "tozan_book/chapter5/", 
  overwrite = TRUE
)

 googledriveパッケージのdrive_mv()で、Googleドライブ上のファイルを移動できます。詳しくは5-3節を参照してください。
 file引数には、シートIDの他にファイルIDなども指定できます。

 以降は、Googleドライブ上の「tozan_bookフォルダ」の中の「chapter5フォルダ」に「penguins」というファイル名でアップロード(作成・保存)したスプレッドシートを使って、メタデータの取得とシートの読み込み・追加を行います。

メタデータの取得

 次に、Google Drive上のファイルの操作に利用するメタデータについて確認しておきます。ファイルのメタデータ(dribbleオブジェクト)とファイルID(drive_idオブジェクト)については「5-3:googledriveパッケージによるファイルのアップロード【R登山本】 - からっぽのしょこ」を参照してください。
 ただし、どのタイプのメタデータも利用できるので、不要であれば飛ばしてください。

 まずは、Googleドライブ上のファイルのメタデータを取得します。

# ドライブ上のファイルのメタデータを取得
metadata_dribble <- googledrive::drive_get(path = "tozan_book/chapter5/penguins")

# シートIDからファイルのメタデータを取得
metadata_dribble <- googledrive::as_dribble(metadata_sheets_id)
metadata_dribble
## # A dribble: 1 x 3
##   name     id                                           drive_resource   
##   <chr>    <drv_id>                                     <list>           
## 1 penguins 1hWwpppTaXwbXpJOmoEbxU-gD1DnFIsHHEDKg5FcNo28 <named list [36]>

 drive_get()にファイルパスを指定するか、as_dribble()にファイルIDまたはシートIDを指定します。ファイルのメタデータは、dribbleオブジェクト(データフレーム)として扱われます。

 ファイルIDを取得します。

# ファイルのメタデータからファイルIDを取得
metadata_drive_id <- metadata_dribble[["id"]]
metadata_drive_id <- googledrive::as_id(metadata_dribble)

# シートIDからファイルIDを取得
metadata_drive_id <- googledrive::as_id(metadata_sheets_id)
metadata_drive_id
## <drive_id[1]>
## [1] 1hWwpppTaXwbXpJOmoEbxU-gD1DnFIsHHEDKg5FcNo28

 dribbleオブジェクトのid列を取り出すか、as_id()にファイルのメタデータまたはシートIDを指定します。ファイルIDは、drive_idオブジェクトとして扱われます。

 シートIDを取得します。

# ファイルのメタデータからシートIDを取得
metadata_sheets_id <- googlesheets4::as_sheets_id(metadata_dribble)

# ファイルIDからシートIDを取得
metadata_sheets_id <- googlesheets4::as_sheets_id(metadata_drive_id)
metadata_sheets_id
## Spreadsheet name: penguins
##               ID: 1hWwpppTaXwbXpJOmoEbxU-gD1DnFIsHHEDKg5FcNo28
##           Locale: ja_JP
##        Time zone: Etc/GMT
##      # of sheets: 1
## 
## (Sheet name): (Nominal extent in rows x columns)
##       Sheet1: 345 x 8

 as_sheets_id()に、ファイルのメタデータまたはファイルIDを指定します。シートIDは、sheets_idオブジェクトとして扱われます。ID自体はファイルIDと同じです。

 スプレッドシートのメタデータを取得します。

# スプレッドシートのメタデータを取得
metadata_gs4_list <- googlesheets4::gs4_get(ss = metadata_dribble)
metadata_gs4_list <- googlesheets4::gs4_get(ss = metadata_drive_id)
metadata_gs4_list <- googlesheets4::gs4_get(ss = metadata_sheets_id)
metadata_gs4_list
## Spreadsheet name: penguins
##               ID: 1hWwpppTaXwbXpJOmoEbxU-gD1DnFIsHHEDKg5FcNo28
##           Locale: ja_JP
##        Time zone: Etc/GMT
##      # of sheets: 1
## 
## (Sheet name): (Nominal extent in rows x columns)
##       Sheet1: 345 x 8

 gs4_get()に、ファイルのメタデータまたはファイルID、シートIDを指定します。スプレッドシートのメタデータは、googlesheets4_spreadsheetオブジェクト(リスト)として扱われます。
 コンソールに表示される内容はシートID(sheets_idオブジェクト)と同じですが、保持している内容は異なります。

# 中身を確認
summary(metadata_gs4_list)
##                 Length Class  Mode     
## spreadsheet_id  1      -none- character
## spreadsheet_url 1      -none- character
## name            1      -none- character
## locale          1      -none- character
## time_zone       1      -none- character
## sheets          8      tbl_df list

 (こういうときはsummaryでいいのでしょうか?S3クラスとやらのことは全然知らないので触れないように書いているので注意してください。)

 スプレッドシートのメタデータ(リスト)から、シートの内容の情報を取り出してみます。

# シートのメタデータからシートの情報を抽出
metadata_gs4_list[["sheets"]]
## # A tibble: 1 x 8
##   name   index         id type  visible grid_rows grid_columns data  
##   <chr>  <int>      <int> <chr> <lgl>       <int>        <int> <list>
## 1 Sheet1     0 1382040153 GRID  TRUE          345            8 <NULL>

 データフレームとして格納されています。
 さらに、シート名の情報を取り出してみます。

# シートのメタデータからシート名を抽出
metadata_gs4_list[["sheets"]][["name"]]
## [1] "Sheet1"

 始めに指定したシート名になっているのを確認できました。

 スプレッドシートのメタデータからファイルIDを取得します。

# シートのメタデータからファイルIDを抽出
metadata_drive_id <- googledrive::as_id(metadata_gs4_list)
metadata_drive_id
## <drive_id[1]>
## [1] 1hWwpppTaXwbXpJOmoEbxU-gD1DnFIsHHEDKg5FcNo28

 as_id()にスプレッドシートのメタデータを指定します。

 スプレッドシートのメタデータからシートIDを取得します。

# シートのメタデータからシートIDを抽出
metadata_sheets_id <- metadata_gs4_list[["spreadsheet_id"]]
metadata_sheets_id <- googlesheets4::as_sheets_id(metadata_gs4_list)
metadata_sheets_id
## Spreadsheet name: penguins
##               ID: 1hWwpppTaXwbXpJOmoEbxU-gD1DnFIsHHEDKg5FcNo28
##           Locale: ja_JP
##        Time zone: Etc/GMT
##      # of sheets: 1
## 
## (Sheet name): (Nominal extent in rows x columns)
##       Sheet1: 345 x 8

 googlesheets4_spreadsheetオブジェクトのspreadsheet_idを取り出すか、as_sheets_id()にスプレッドシートのメタデータを指定します。

シートの読み込み

 googlesheets4パッケージを利用して、Google Drive上のスプレッドシートをデータフレームとして読み込みます。

 データを読み込むスプレッドシートのシートIDを取得します。

# シートIDを取得
metadata_sheets_id <- googledrive::drive_get(path = "tozan_book/chapter5/penguins") %>% 
  googlesheets4::as_sheets_id()

 drive_get()にファイルパスを指定して、ファイルのメタデータ(dribbleオブジェクト)を取得します。

 指定したスプレッドシートからデータを読み込みます。

# デフォルトの設定でデータを取得
df_default <- googlesheets4::read_sheet(ss = metadata_sheets_id)
head(df_default)
head(df_default)
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <chr>   <chr>           <dbl>         <dbl>            <dbl>       <dbl> <chr>
## 1 Adelie  Torge~           39.1          18.7              181        3750 male 
## 2 Adelie  Torge~           39.5          17.4              186        3800 fema~
## 3 Adelie  Torge~           40.3          18                195        3250 fema~
## 4 Adelie  Torge~           NA            NA                 NA          NA <NA> 
## 5 Adelie  Torge~           36.7          19.3              193        3450 fema~
## 6 Adelie  Torge~           39.3          20.6              190        3650 male 
## # ... with 1 more variable: year <dbl>

 read_sheet()で、スプレッドシートの内容を読み込みます。googlesheets4パッケージの命名規則に沿ったrange_read()と同じ関数です。
 ss引数(第1引数)に、スプレッドシートのメタデータ(dribbledrive_idsheets_idオブジェクト)を指定します。

 読み込み時の処理を引数で設定できます。

# データを取得
df <- googlesheets4::read_sheet(
  ss = metadata_sheets_id, 
  sheet = "Sheet1", 
  col_types = "ccddiici", 
  na = c("", "NA")
) %>% 
  # 文字列NAを欠損値NAに変換
  dplyr::mutate(
    species = factor(species), 
    island = factor(island), 
    sex = factor(sex)
  )
head(df)
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <fct>   <fct>           <dbl>         <dbl>            <int>       <int> <fct>
## 1 Adelie  Torge~           39.1          18.7              181        3750 male 
## 2 Adelie  Torge~           39.5          17.4              186        3800 fema~
## 3 Adelie  Torge~           40.3          18                195        3250 fema~
## 4 Adelie  Torge~           NA            NA                 NA          NA <NA> 
## 5 Adelie  Torge~           36.7          19.3              193        3450 fema~
## 6 Adelie  Torge~           39.3          20.6              190        3650 male 
## # ... with 1 more variable: year <int>

 sheet引数に、読み込むシートを指定します。シート名またはシート番号を指定できます。デフォルトは1番目のシートです。
 col_types引数に、列ごとの型を指定します。
 na引数に、欠損値として扱う値を指定します。デフォルトは空白セル("")です。この例では、空白と文字列のNA("NA")をベクトルで指定しています。
 因子型の場合は、factor()で変換する必要があります。

メモ

 最終的に書き出し・読み込み時の引数の設定でスマートに処理できたのですが、試行錯誤していた際にあれこれしたメモです。不要であれば飛ばしてください。

 readr::write_csv()で書き出す際に、na引数を指定しないと欠損値が文字列NAとして書き出されます。そのデータをgooglesheets4::read_sheet()で読み込む際に、na引数を指定しないと次のようになりました。

# データフレームをローカルに書き出し
readr::write_csv(
  x = penguins_df, 
  file = "data/tmp_penguins.csv"
)

# スプレッドシートとしてアップロード
googledrive::drive_put(
  media = "data/tmp_penguins.csv", 
  path = "tozan_book/chapter5/", 
  name = "tmp_penguins", 
  type = "spreadsheet", 
)

# シートIDを取得
tmp_metadata_sheets_id <- googledrive::drive_get(path = "tozan_book/chapter5/tmp_penguins") %>% 
  googlesheets4::as_sheets_id()

# デフォルトの設定でデータを取得
df_default <- googlesheets4::read_sheet(ss = tmp_metadata_sheets_id)

# デフォルトの設定の場合
head(df_default)
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <chr>   <chr>  <list>         <list>        <list>           <list>      <chr>
## 1 Adelie  Torge~ <dbl [1]>      <dbl [1]>     <dbl [1]>        <dbl [1]>   male 
## 2 Adelie  Torge~ <dbl [1]>      <dbl [1]>     <dbl [1]>        <dbl [1]>   fema~
## 3 Adelie  Torge~ <dbl [1]>      <dbl [1]>     <dbl [1]>        <dbl [1]>   fema~
## 4 Adelie  Torge~ <chr [1]>      <chr [1]>     <chr [1]>        <chr [1]>   NA   
## 5 Adelie  Torge~ <dbl [1]>      <dbl [1]>     <dbl [1]>        <dbl [1]>   fema~
## 6 Adelie  Torge~ <dbl [1]>      <dbl [1]>     <dbl [1]>        <dbl [1]>   male 
## # ... with 1 more variable: year <dbl>

 1つの列に数値と文字列が含まれていると、リスト形式になるようです(?)。

・処理コードの解説(クリックで展開)

 unlist()で、リストからベクトルに変換します。

# データフレームを調整
df_default %>% 
  # リスト型の列からベクトル型の列に変換
  dplyr::mutate(
    bill_length_mm = unlist(bill_length_mm), 
    bill_depth_mm = unlist(bill_depth_mm), 
    flipper_length_mm = unlist(flipper_length_mm), 
    body_mass_g = unlist(body_mass_g)
  ) %>% 
  head()
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <chr>   <chr>  <chr>          <chr>         <chr>            <chr>       <chr>
## 1 Adelie  Torge~ 39.1           18.7          181              3750        male 
## 2 Adelie  Torge~ 39.5           17.4          186              3800        fema~
## 3 Adelie  Torge~ 40.3           18            195              3250        fema~
## 4 Adelie  Torge~ NA             NA            NA               NA          NA   
## 5 Adelie  Torge~ 36.7           19.3          193              3450        fema~
## 6 Adelie  Torge~ 39.3           20.6          190              3650        male 
## # ... with 1 more variable: year <dbl>

 1つの列(ベクトル)には同じ型の値しか持てないので、全ての値が文字列型に変換されました。
 as.numeric()で数値型に、as.integer()で整数型に変換します。

# データフレームを調整
df_default %>% 
  # リスト型の列からベクトル型の列に変換
  dplyr::mutate(
    bill_length_mm = unlist(bill_length_mm), 
    bill_depth_mm = unlist(bill_depth_mm), 
    flipper_length_mm = unlist(flipper_length_mm), 
    body_mass_g = unlist(body_mass_g)
  ) %>% 
  # 文字列型から整数型・数値型に変換
  dplyr::mutate(
    bill_length_mm = as.numeric(bill_length_mm), 
    bill_depth_mm = as.numeric(bill_depth_mm), 
    flipper_length_mm = as.integer(flipper_length_mm), 
    body_mass_g = as.integer(body_mass_g), 
    year = as.integer(year)
  ) %>% 
  head()
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <chr>   <chr>           <dbl>         <dbl>            <int>       <int> <chr>
## 1 Adelie  Torge~           39.1          18.7              181        3750 male 
## 2 Adelie  Torge~           39.5          17.4              186        3800 fema~
## 3 Adelie  Torge~           40.3          18                195        3250 fema~
## 4 Adelie  Torge~           NA            NA                 NA          NA NA   
## 5 Adelie  Torge~           36.7          19.3              193        3450 fema~
## 6 Adelie  Torge~           39.3          20.6              190        3650 male 
## # ... with 1 more variable: year <int>

 数値型・整数型に変換される際に、文字列"NA"が欠損値NAに変換されました。
 文字列型に読み込まれた列についても、欠損値に置換します。

# データフレームを調整
df_default %>% 
  # リスト型の列からベクトル型の列に変換
  dplyr::mutate(
    bill_length_mm = unlist(bill_length_mm), 
    bill_depth_mm = unlist(bill_depth_mm), 
    flipper_length_mm = unlist(flipper_length_mm), 
    body_mass_g = unlist(body_mass_g)
  ) %>% 
  # 文字列型から整数型・数値型に変換
  dplyr::mutate(
    bill_length_mm = as.numeric(bill_length_mm), 
    bill_depth_mm = as.numeric(bill_depth_mm), 
    flipper_length_mm = as.integer(flipper_length_mm), 
    body_mass_g = as.integer(body_mass_g), 
    year = as.integer(year)
  ) %>% 
  # 文字列NAを欠損値NAに変換
  dplyr::mutate(
    species = dplyr::if_else(species == "NA", true = as.character(NA), false = species), 
    island = dplyr::if_else(island == "NA", true = as.character(NA), false = island), 
    sex = dplyr::if_else(sex == "NA", true = NA_character_, false = sex)
  ) %>% 
  head()
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <chr>   <chr>           <dbl>         <dbl>            <int>       <int> <chr>
## 1 Adelie  Torge~           39.1          18.7              181        3750 male 
## 2 Adelie  Torge~           39.5          17.4              186        3800 fema~
## 3 Adelie  Torge~           40.3          18                195        3250 fema~
## 4 Adelie  Torge~           NA            NA                 NA          NA <NA> 
## 5 Adelie  Torge~           36.7          19.3              193        3450 fema~
## 6 Adelie  Torge~           39.3          20.6              190        3650 male 
## # ... with 1 more variable: year <int>

 欠損値NAにも型があるため、文字列型の欠損値NA_character_を使う必要があります。as.character(NA)でも処理できます。整数型であればNA_integer_、数値型であればNA_real_です。
 最後に、factor()で、文字列型から因子型に変換します。

# データフレームを調整
df_default %>% 
  # リスト型の列からベクトル型の列に変換
  dplyr::mutate(
    bill_length_mm = unlist(bill_length_mm), 
    bill_depth_mm = unlist(bill_depth_mm), 
    flipper_length_mm = unlist(flipper_length_mm), 
    body_mass_g = unlist(body_mass_g)
  ) %>% 
  # 文字列型から整数型・数値型に変換
  dplyr::mutate(
    bill_length_mm = as.numeric(bill_length_mm), 
    bill_depth_mm = as.numeric(bill_depth_mm), 
    flipper_length_mm = as.integer(flipper_length_mm), 
    body_mass_g = as.integer(body_mass_g), 
    year = as.integer(year)
  ) %>% 
  # 文字列NAを欠損値NAに変換
  dplyr::mutate(
    species = dplyr::if_else(species == "NA", true = NA_character_, false = species), 
    island = dplyr::if_else(island == "NA", true = NA_character_, false = island), 
    sex = dplyr::if_else(sex == "NA", true = NA_character_, false = sex)
  ) %>% 
  # 文字列型から因子型に変換
  dplyr::mutate(
    species = factor(species), 
    island = factor(island), 
    sex = factor(sex)
  ) %>% 
  head()
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <fct>   <fct>           <dbl>         <dbl>            <int>       <int> <fct>
## 1 Adelie  Torge~           39.1          18.7              181        3750 male 
## 2 Adelie  Torge~           39.5          17.4              186        3800 fema~
## 3 Adelie  Torge~           40.3          18                195        3250 fema~
## 4 Adelie  Torge~           NA            NA                 NA          NA <NA> 
## 5 Adelie  Torge~           36.7          19.3              193        3450 fema~
## 6 Adelie  Torge~           39.3          20.6              190        3650 male 
## # ... with 1 more variable: year <int>


 ここまでの処理をまとめて行います。

# データフレームを調整
df2 <- df_default %>% 
  dplyr::mutate(
    species = dplyr::if_else(species == "NA", true = NA_character_, false = species) %>% 
      factor(), 
    island = dplyr::if_else(island == "NA", true = NA_character_, false = island) %>% 
      factor(), 
    bill_length_mm = unlist(bill_length_mm) %>% 
      as.numeric(), 
    bill_depth_mm = unlist(bill_depth_mm) %>% 
      as.numeric(), 
    flipper_length_mm = unlist(flipper_length_mm) %>% 
      as.integer(), 
    body_mass_g = unlist(body_mass_g) %>% 
      as.integer(), 
    year = as.integer(year), 
    sex = dplyr::if_else(sex == "NA", true = NA_character_, false = sex) %>% 
      factor()
  )
head(df2)
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <fct>   <fct>           <dbl>         <dbl>            <int>       <int> <fct>
## 1 Adelie  Torge~           39.1          18.7              181        3750 male 
## 2 Adelie  Torge~           39.5          17.4              186        3800 fema~
## 3 Adelie  Torge~           40.3          18                195        3250 fema~
## 4 Adelie  Torge~           NA            NA                 NA          NA <NA> 
## 5 Adelie  Torge~           36.7          19.3              193        3450 fema~
## 6 Adelie  Torge~           39.3          20.6              190        3650 male 
## # ... with 1 more variable: year <int>

 元のデータフレームが得られました。

シートの書き出し

 googlesheets4パッケージを利用して、データフレームをGoogle Drive上のスプレッドシートに書き出します。

 分かりやすいように、データフレームの内容を書き替えておきます。

# NAを含む行を削除
df_drop_na <- tidyr::drop_na(df)  
head(df_drop_na)
## # A tibble: 6 x 8
##   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g sex  
##   <fct>   <fct>           <dbl>         <dbl>            <int>       <int> <fct>
## 1 Adelie  Torge~           39.1          18.7              181        3750 male 
## 2 Adelie  Torge~           39.5          17.4              186        3800 fema~
## 3 Adelie  Torge~           40.3          18                195        3250 fema~
## 4 Adelie  Torge~           36.7          19.3              193        3450 fema~
## 5 Adelie  Torge~           39.3          20.6              190        3650 male 
## 6 Adelie  Torge~           38.9          17.8              181        3625 fema~
## # ... with 1 more variable: year <int>

 drop_na()で、欠損値を含む行を削除できます。

 既存のスプレッドシートに、新しいシートとして書き出します。

# シートを追加
googlesheets4::write_sheet(
  data = df_drop_na, 
  ss = metadata_sheets_id, 
  sheet = "drop_na"
)

 write_sheet()で、既存のスプレッドシートにシートを追加します。googlesheets4パッケージの命名規則に沿ったsheet_write()と同じ関数です。
 data引数(第1引数)に、データフレームを指定します。
 ss引数に、スプレッドシートのメタデータ(dribbledrive_idsheets_idオブジェクト)を指定します。
 sheet引数に、シート名を指定します。既存のシート名を指定するとそのシートの内容が書き替えられます。

 スプレッドシートのメタデータを確認してみます。

# シートのメタデータを取得
metadata_gs4_list <- googlesheets4::gs4_get(ss = metadata_sheets_id)
metadata_gs4_list
## Spreadsheet name: penguins
##               ID: 1hWwpppTaXwbXpJOmoEbxU-gD1DnFIsHHEDKg5FcNo28
##           Locale: ja_JP
##        Time zone: Etc/GMT
##      # of sheets: 2
## 
## (Sheet name): (Nominal extent in rows x columns)
##       Sheet1: 345 x 8
##      drop_na: 334 x 8

 シートが追加されているのが分かります。また、ファイルIDは変わりません。

 以上で、Google Driveにスプレッドシートに読み込み・書き出しを行う方法を確認しました。

参考書籍

  • 「Rが生産性を高める 〜データ分析ワークフロー効率化の実践」igjit・atusy・hanaori 著,技術評論社,2022年.

おわりに

 読み込み時に少し詰まったのでそれについてまとめるつもりで書き始めましたが、調べてると引数の設定で解決してしまい書きたかったメインの話がなくなってしました。まぁそれだけ便利なパッケージだということです。
 ただ欠損値にも型があることを初めて知ったので、「メモ」として書いておきたかった次第です。

 エンディング曲をどうぞ♪

 その時々のメンバーによる再録版楽曲もっと出してほしー。

【次の内容】

www.anarchive-beta.com