Rを使いデータフレームに色々入れてみる

データフレーム準備

「R言語」で作る「tibble」形式のデータフレームには色々なオブジェクトが入れられるそうです。

→参考サイトはこちら

試してみました。

# irisデータを使う

library(tidyverse)

data(iris)
## tibble形式に変換
iris_df <-
  as_tibble(iris)
iris_df

# A tibble: 150 × 5
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          <dbl>       <dbl>        <dbl>       <dbl> <fct>  
 1          5.1         3.5          1.4         0.2 setosa 
 2          4.9         3            1.4         0.2 setosa 
 3          4.7         3.2          1.3         0.2 setosa 
 4          4.6         3.1          1.5         0.2 setosa 
 5          5           3.6          1.4         0.2 setosa 
 6          5.4         3.9          1.7         0.4 setosa 
 7          4.6         3.4          1.4         0.3 setosa 
 8          5           3.4          1.5         0.2 setosa 
 9          4.4         2.9          1.4         0.2 setosa 
10          4.9         3.1          1.5         0.1 setosa 
# … with 140 more rows
# ℹ Use `print(n = ...)` to see more rows

データフレームにデータフレームを入れる

後出のデータフレーム「iris_df_A」の内容確認で、「<tibble [50 × 5]>」と50行x5列のデータフレームを収録していることを示しています。

# 種類(Species)を確認
iris_Spec <- 
  iris_df %>% 
  distinct(Species)
iris_Spec

# A tibble: 3 × 1
Species   
<fct>     
1 setosa    
2 versicolor
3 virginica 
# 種類を行項目とし、データフレームの中に
# 種類別のデータフレームを収録
# まず各種類別のデータフレームを作る

# "setosa"だけを含むデータフレーム
iris_df_set <-
  iris_df %>% 
  filter(Species == "setosa")
iris_df_set

# "versicolor"だけを含むデータフレーム
iris_df_ver <-
  iris_df %>% 
  filter(Species == "versicolor")
iris_df_ver

# "virginica"だけを含むデータフレーム
iris_df_vir <-
  iris_df %>% 
  filter(Species == "virginica")
iris_df_vir
# 上記3つのデータフレームを
# 「setosa」「versicolor」「virginica」格行の2列目に収録

iris_df_A <-
  iris_Spec %>% 
  mutate(
    Species_df =
      list(
        iris_df_set, iris_df_ver, iris_df_vir
        )
  )
iris_df_A

# A tibble: 3 × 2
  Species    Species_df       
  <fct>      <list>           
1 setosa     <tibble [50 × 5]>
2 versicolor <tibble [50 × 5]>
3 virginica  <tibble [50 × 5]>
# 確認
iris_df_A %>%
  pluck("Species_df", 1)

# A tibble: 50 × 5
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          <dbl>       <dbl>        <dbl>       <dbl> <fct>  
 1          5.1         3.5          1.4         0.2 setosa 
 2          4.9         3            1.4         0.2 setosa 
 3          4.7         3.2          1.3         0.2 setosa 
 4          4.6         3.1          1.5         0.2 setosa 
 5          5           3.6          1.4         0.2 setosa 
 6          5.4         3.9          1.7         0.4 setosa 
 7          4.6         3.4          1.4         0.3 setosa 
 8          5           3.4          1.5         0.2 setosa 
 9          4.4         2.9          1.4         0.2 setosa 
10          4.9         3.1          1.5         0.1 setosa 
# … with 40 more rows
# ℹ Use `print(n = ...)` to see more rows

データフレームにグラフを収録(散布図)

後述のデータフレーム「iris_df_B」の内容確認で、「<gg>」というグラフオブジェクトを収録している状態を表示しています。

# グラフも収録
# まずグラフを作成

# 散布図
iris_df_set2 <-
  iris_df_set %>% 
  ggplot(
    aes(x = Sepal.Length, y = Petal.Length)
    ) +
  geom_point() + 
  theme_bw()

iris_df_ver2 <-
  iris_df_ver %>% 
  ggplot(
    aes(x = Sepal.Length, y = Petal.Length)
  ) +
  geom_point() + 
  theme_bw()

iris_df_vir2 <-
  iris_df_vir %>% 
  ggplot(
    aes(x = Sepal.Length, y = Petal.Length)
  ) +
  geom_point() + 
  theme_bw()
# データフレームに収録
iris_df_B <-
  iris_df_A %>% 
  mutate(
    Species_gg1 =
      list(
        iris_df_set2, iris_df_ver2, iris_df_vir2
      )
  )
iris_df_B

# A tibble: 3 × 3
  Species    Species_df        Species_gg1
  <fct>      <list>            <list>     
1 setosa     <tibble [50 × 5]> <gg>       
2 versicolor <tibble [50 × 5]> <gg>       
3 virginica  <tibble [50 × 5]> <gg>     
# 確認
iris_df_B %>%
  pluck("Species_gg1", 1)

データフレームにグラフを収録(棒グラフ)

同様にグラフオブジェクト「<gg>」がデータフレームに入っています。

# 棒グラフ。Sepal.Widthの値の個数をy軸に
iris_df_set3 <-
  iris_df_set %>% 
  ggplot(
    aes(x = Sepal.Width)
  ) +
  geom_bar() + 
  theme_classic()
iris_df_set3

iris_df_ver3 <-
  iris_df_ver %>% 
  ggplot(
    aes(x = Sepal.Width)
  ) +
  geom_bar() + 
  theme_classic()
iris_df_ver3

iris_df_vir3 <-
  iris_df_vir %>% 
  ggplot(
    aes(x = Sepal.Width)
  ) +
  geom_bar() + 
  theme_classic()
iris_df_vir3
# データフレームに収録
iris_df_C <-
  iris_df_B %>% 
  mutate(
    Species_gg2 =
      list(
        iris_df_set3, iris_df_ver3, iris_df_vir3
      )
  )
iris_df_C

# A tibble: 3 × 4
  Species    Species_df        Species_gg1 Species_gg2
  <fct>      <list>            <list>      <list>     
1 setosa     <tibble [50 × 5]> <gg>        <gg>       
2 versicolor <tibble [50 × 5]> <gg>        <gg>       
3 virginica  <tibble [50 × 5]> <gg>        <gg>    
# 確認
iris_df_C %>%
  pluck("Species_gg2", 2)

データフレームに関数を収録(1)

変数にデータフレームを使う関数を用意します。
後出の「<fn>」が関数オブジェクトです。

# 関数準備
# 自作関数作成。
# データフレームを変数にし、Sepal.Length >= 5.5をピックアップする関数
SepalLength_F = function(df){
  pick_SepalLength = 
    df %>% 
    filter(Sepal.Length >= 5.5)
  return(pick_SepalLength)
}
# 関数をデータフレームに追加
iris_df_C_func = 
  iris_df_C %>% 
  mutate(
    func = 
      list(
        SepalLength_F
      )
  ) 
iris_df_C_func

# A tibble: 3 × 5
  Species    Species_df        Species_gg1 Species_gg2 func  
  <fct>      <list>            <list>      <list>      <list>
1 setosa     <tibble [50 × 5]> <gg>        <gg>        <fn>  
2 versicolor <tibble [50 × 5]> <gg>        <gg>        <fn>  
3 virginica  <tibble [50 × 5]> <gg>        <gg>        <fn>  
# 確認
# 「<bytecode: 0x14baccbc8>」は関数のバイトコードオブジェクトで、
# このオブジェクト自体には問題なそうです。
iris_df_C_func %>%
  pluck("func", 1)

function(df){
  pick_SepalLength = 
    df %>% 
    filter(Sepal.Length >= 5.5)
  return(pick_SepalLength)
}
<bytecode: 0x14baccbc8>

作成した関数の振る舞いは以下のようになります。

# 関数動作確認
iris_df_C_func %>% pluck("Species_df", 1) %>% 
  SepalLength_F()

# A tibble: 5 × 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
         <dbl>       <dbl>        <dbl>       <dbl> <fct>  
1          5.8         4            1.2         0.2 setosa 
2          5.7         4.4          1.5         0.4 setosa 
3          5.7         3.8          1.7         0.3 setosa 
4          5.5         4.2          1.4         0.2 setosa 
5          5.5         3.5          1.3         0.2 setosa 

関数適用結果をデータフレームに入れる(1)

関数にデータフレームを代入し出力した結果をデータフレームに入れてみます。
しかし、エラーが出てしまいました。

# 関数適用結果をデータフレームに収録

iris_df_C_func_output = 
  iris_df_C_func %>% 
  mutate(
    func_output = 
      list(
        func(Species_df)
      )
  )

Error in `mutate()`:
! Problem while computing `func_output = list(func(Species_df))`.
Caused by error in `func()`:
! could not find function "func"
Run `rlang::last_error()` to see where the error occurred.

このエラーの解決方法がわかりませんでした
この関数が入っているデータフレーム「iris_df_C_func」を見ると、「Species_df」列が「<list>」型になっています。

iris_df_C_func

# A tibble: 3 × 5
  Species    Species_df        Species_gg1 Species_gg2 func  
  <fct>      <list>            <list>      <list>      <list>
1 setosa     <tibble [50 × 5]> <gg>        <gg>        <fn>  
2 versicolor <tibble [50 × 5]> <gg>        <gg>        <fn>  
3 virginica  <tibble [50 × 5]> <gg>        <gg>        <fn>  


<list<tibble[,x]>>」という型にしないといけないようです。
この型への変換方法がわかりませんでした。

データフレームに関数を収録(2)

今回は、関数をデータフレームに収録する確認は、参考にしたサイト同様に「nest_by」関数を使うことにしました。
nest_by」で種類別のデータフレームをデータフレームに収録し、併せて先ほど作った関数を「func」という列に入れています。
(グラフの収録はしていません)

##ここでnest_by使ってみる
# 自作関数追加

iris_df_C_func_output2 = 
  iris %>% 
  nest_by(Species) %>% 
  mutate(
    func = 
      list(
        SepalLength_F
      )
  )
iris_df_C_func_output2

# A tibble: 3 × 3
# Rowwise:  Species
  Species                  data func  
  <fct>      <list<tibble[,4]>> <list>
1 setosa               [50 × 4] <fn>  
2 versicolor           [50 × 4] <fn>  
3 virginica            [50 × 4] <fn>  

(自動でできる)「data」列は「<list<tibble[,4]>>」という型の列の中に、データフレームが入っています。

関数適用結果をデータフレームに入れる(2)

改めて関数にデータフレームを代入し出力した結果をデータフレームに入れてみます。
今回は収録できました。

# 関数適用
iris_func_Result2 = 
  iris_df_C_func_output2 %>% 
  mutate(
    df_SepalLength_out = 
      list(
        func(data)
      )
  )
iris_func_Result2

# A tibble: 3 × 4
# Rowwise:  Species
  Species                  data func   df_SepalLength_out
  <fct>      <list<tibble[,4]>> <list> <list>            
1 setosa               [50 × 4] <fn>   <tibble [5 × 4]>  
2 versicolor           [50 × 4] <fn>   <tibble [44 × 4]> 
3 virginica            [50 × 4] <fn>   <tibble [49 × 4]> 
# 確認
iris_func_Result2 %>%
  pluck("df_SepalLength_out", 1)

# A tibble: 5 × 4
  Sepal.Length Sepal.Width Petal.Length Petal.Width
         <dbl>       <dbl>        <dbl>       <dbl>
1          5.8         4            1.2         0.2
2          5.7         4.4          1.5         0.4
3          5.7         3.8          1.7         0.3
4          5.5         4.2          1.4         0.2
5          5.5         3.5          1.3         0.2
タイトルとURLをコピーしました