行・列の追加

行の追加

tibble::add_row

  • dplyr::add_row も同じ(tibble::add_rowが呼び出される)
  • 引数内では、“列名 = 格納する値” の形式で記述していく
  • 複数行を一括で追加したいなら、dplyr::bind_rows 関数の方が便利かも
    • 「データフレームの結合」を参照
tokyo <- tibble::tribble(
  ~year, ~max_temp, ~min_temp,
  2000, 37.8, -0.7,
  2001, 38.1, -2.4,
  2002, 35.8, -0.3,
  2003, 34.3, -0.8,
  2004, 39.5, 0.2,
  2005, 36.2, -0.8,
  2006, 36.1, -1.5,
  2007, 37.5, 0.2,
  2008, 35.3, -0.1,
  2009, 34.2, 0,
)

tokyo |> 
  tibble::add_row(
    year = 2010,
    max_temp = 37.2,
    min_temp = -0.4
  ) |> 
  dplyr::arrange(year |> desc())

列の追加

dplyr::mutate

  • mutate(新しい列の名前 = 算出式, …)
  • 新しい列は、デフォルトではデータフレームの一番右に追加される
  • 既存の列名を指定すれば上書きが可能
  • .beforeオプションや.afterオプションを指定すれば、列を追加する位置を指定できる
dplyr::starwars |> 
  dplyr::mutate(
    height = height / 100,
    bmi = mass / (height ^ 2), .after = mass)
  • 単一条件で分岐して、新しい列にデータを追加: mutate(変数名 = if_else())
    • ダミー変数を作る際に使える
  • 欠損値の箇所はFALSEとなる
    • missingオプションを指定することで、別の値への置き換えが可能
dplyr::starwars |> 
  dplyr::mutate(
    height = height / 100,
    bmi = mass / (height ^ 2), .after = mass) |> 
  dplyr::mutate(
    bmi_is_obese = dplyr::if_else(bmi >= 30, 1, 0), # bmi 30 以上を肥満とするダミー変数
    .after = bmi
    ) 
# 分かりやすいようにmutateを2つ連ねて書いたが、本来は1つにまとめてOK (ただし順番は注意)
  • 複数条件で分岐して、新しい列にデータを追加: mutate(変数名 = case_when())
  • 条件 ~ 値 の形式で書き連ねていく
    • どの条件にも当てはまらないケースは、.default オプションで条件を指定することで定義可
dplyr::starwars |> 
  dplyr::mutate(
    height = height / 100,
    bmi = mass / (height ^ 2), .after = mass) |> 
  dplyr::mutate(
    bmi_is_obese = dplyr::case_when(
      bmi < 18.5 ~ "痩せ",
      bmi < 25 ~ "普通",
      .default = "肥満"
      ),
    .after = bmi
    ) 
# 分かりやすいようにmutateを2つ連ねて書いたが、本来は1つにまとめてOK (ただし順番は注意)
  • 列の追加分のみを残したい場合は、 .keep = “none” と指定する
  • 列の追加分に加え、mutate内で算出に使った列も残したい場合は、.keep = “used” と指定
dplyr::starwars |> 
  dplyr::mutate(
    name,
    bmi = mass / ((height / 100) ^ 2),
    .keep = "none"
  )

順位の列の追加

順位付けの際に、mutate関数などで使用できる便利な関数は次の通り

  • min_rank() : 一般的な順位(重複分だけ順位カウント)
    • 例: 5, 5, 3 -> 1位, 1位, 3位
    • percent_rank() : min_rank() の値を 0~1に収まるように標準化したもの
    • dense_rank() : 順位カウントの際、重複分は1つとみなす
      • 例: 5, 5, 3 -> 1位, 1位, 2位
    • ntile(x, n) : 順位をもとに,n個のグループにxを分類

tidyr::population |> 
  dplyr::filter(year == 2013) |>
  dplyr::mutate(
    population = population |> round(digits = -5), # 人口を10万で丸める
    rank_pop = dplyr::min_rank(population |> dplyr::desc()), # 降順に順位付け
    rank_pop_group = dplyr::ntile(rank_pop, 5), # 順位をもとに5つのグループに分類
    .after = year
  ) |> 
  dplyr::arrange(rank_pop)

行番号の列の追加

1行ごとに振っていく場合

  • tibble::rowid_to_column(“追加する列名”) が便利
    • 番号を文字列として追加する場合は tibble::rownames_to_column(“追加する列名”)
dplyr::starwars |> 
  tibble::rowid_to_column("id")

内容が変わらなければ番号を据え置く場合

  • dplyr::consecutive_id(列)

    • 指定した列の内容をもとに番号を振っていく
    • 上から順に振っていき、内容が変わらなければ数値はそのまま。変わるたびに1足されていく
dplyr::storms |> 
  dplyr::mutate(
     name_and_year = stringr::str_c(name, year, sep = "_"),
    consec_id = dplyr::consecutive_id(name_and_year),
    .before = "name"
    ) |> 
  dplyr::relocate(consec_id)

ラグ項・リード項の追加

  • dplyr::lag( 列名 ) : 1つ上の項目の値を取得
    • 列名の後にnオプションで数値を指定すれば、指定した数だけ上の値を取得
  • dplyr::lead( 列名 ) : 1つ下の項目の値を取得
    • 列名の後にnオプションで数値を指定すれば、指定した数だけ下の値を取得
  • 以下の関数も活用できるかも
    • ある列の1番上の行の値: dplyr::first(列名)
    • ある列の1番下の行の値: dplyr::last(列名)
    • ある列のn番目の行の値: dplyr::nth(列名, n)
    • 欠損値を無視したい場合は na_rm = FALSE オプションを指定
tokyo |> 
  dplyr::mutate(
    max_temp_lag = dplyr::lag(max_temp),
    .after = max_temp
  )