読者です 読者をやめる 読者になる 読者になる

Mukku John Blog

取り組んでいること を つらつら と

Rプログラミング入門 9回目

この記事では、
1つのアトミックベクトルは、1つの同じデータ型で構成される事が分かりました。
mukkujohn.hatenablog.com

では1つのアトミックベクトルに、複数のデータ型の要素を割り当てると
どうなるでしょうか?

型強制

character、logical、double型を割り当てて、確認してみます。

> forcedType <- c("ace",TRUE,3)
> forcedType
[1] "ace"  "TRUE" "3"

character型に変換されるため、character型が優先されています。

次に、logical、double型を割り当ててみます。

> numericAndLogicalOnly <- c(TRUE,FALSE,3,303)
> numericAndLogicalOnly
[1]   1   0   3 303

double型に変換されるため、double型が優先されています。

このように、アトミックベクトル内に複数のデータ型が
存在する場合は、この順で型の変換が行われます。

  1. character
  2. double
  3. logical

型の変換を勝手に行われたくない場合は、明示的に指定する必要があります。

> as.character(1)
[1] "1"
> as.character(TRUE)
[1] "TRUE"
> as.numeric("10")
[1] 10
> as.logical(1)
[1] TRUE
> as.numeric(FALSE)
[1] 0

何かしらの演算を行う場合は、型が同じである方が
処理が統一でき、簡単に実行できます。

ただ、多くのデータセットには複数の型の情報が含まれています。
このようなデータセットを扱うためには、どのようにすればよいでしょうか?

リスト

リストは、複数のアトミックベクトルなどを、まとめて割り当てる事ができます。

> list1 <- list(100:130,"R",list(TRUE,FALSE))
> list1
[[1]]
 [1] 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
[19] 118 119 120 121 122 123 124 125 126 127 128 129 130

[[2]]
[1] "R"

[[3]]
[[3]][[1]]
[1] TRUE

[[3]][[2]]
[1] FALSE

1個目の要素は、100から130までのinteger型のアトミックベクトルです。
2個目の要素は、"R"というcharacter型のアトミックベクトルです。
3個目の要素は、リストオブジェクトが割り当てられており、
 そのリスト内の1個目の要素がTRUEのlogical型のアトミックベクトル
 そのリスト内の2個目の要素がFALSEのlogical型のアトミックベクトル
となっています。

この様に、複数のデータ型を扱うためにはリストオブジェクトを利用します。

ただ、リストは柔軟性が高すぎるために、構造が複雑になり得ます。
もう少し、制約を持ちつつ、複数のデータ型を扱いたいものです。

データフレーム

データフレームは、リストの2次元バージョンになります。
しかも、列の要素は、全て同じデータ型である制約も持っています。

> df <- data.frame(face=c("ace","tow","six"),suit=c("clubs","clubs","clubs"),value=c(1,2,3))
> df
  face  suit value
1  ace clubs     1
2  tow clubs     2
3  six clubs     3

長さが異なる列を結合できませんが、リサイクリング規則が適用されます。
data.frame関数は、各引数名を列のラベルとして扱ってくれます。

ここで、dfオブジェクトのデータ型とクラスを確認してみます。

> typeof(df)
[1] "list"
> class(df)
[1] "data.frame"

データ型はlistであり、クラスがdata.frameである事が分かります。

このデータフレームを用いる事で、大量のデータを扱いやすくなります。
ただ、大量のデータを割り当てるためには、手で入力するしかないのでしょうか?

データのロード

手で大量のデータをオブジェクトに割り当てるのは、当然ながら嫌です。
タイプ量も多いし、もちろん間違う可能性も高くなります。

そこで、ファイルを読み込む事ができます。
RStudio
Import Datasetから、From Local File...を選択します。
f:id:MukkuJohn:20160704214512p:plain

ローカルにあるファイルを選択する事で、インポートウィザードが開き、
インポートする際に、ヘッダの有無、区切り文字、修飾文字などを設定できます。
f:id:MukkuJohn:20160704214715p:plain

R Tools for Visual Studio
手順的には、RStudioと同様です。
R Tools -> Data -> Import From Text File...を選択します。
f:id:MukkuJohn:20160704214807p:plain

ローカルにあるファイルを選択する事で、インポートウィザードが開き、
インポートする際に、ヘッダの有無、区切り文字、修飾文字などを設定できます。
f:id:MukkuJohn:20160704214929p:plain

ロードしたデータを確認する場合は、head関数やtail関数で
先頭6行分、末尾6行分確認する事ができます。

> head(deck)
   face   suit value
1  king spades    13
2 queen spades    12
3  jack spades    11
4   ten spades    10
5  nine spades     9
6 eight spades     8
> tail(deck)
    face   suit value
47   six hearts     6
48  five hearts     5
49  four hearts     4
50 three hearts     3
51   two hearts     2
52   ace hearts     1

さて、今回はデータフレームをロードして取得しましたが、
手で作成したデータフレームを保存するにはどうしたらよいでしょうか?

データの保存

データフレームをcsvファイルに保存するためには、write.csv関数を利用します。

> write.csv(deck,file="cards.csv",row.names = FALSE)

この関数を見ると、ファイル名しか指定していませんが、
保存する際に、Rではディレクトリは指定しません。
ディレクトリは、現在の作業ディレクトリが使われます。

現在のディレクトリを確認するためには、getwd関数を利用します。

> getwd()
[1] "C:/○○○/■■■/Documents"

この作業ディレクトリを変更するためには、GUIもしくはsetwd関数を利用します。
まずは、GUIを利用する方法です。
RStudio
ツールバーの、Session -> Set Working Directory -> Choose Directoryを選択します。
f:id:MukkuJohn:20160704220639p:plain
フォルダ選択ダイアログが開きますので、作業ディレクトリを選択します。

R Tools for Visual Studio
R Interactiveウィンドウの右側にフォルダアイコンがあります。
f:id:MukkuJohn:20160704221058p:plain
フォルダ選択ダイアログが開きますので、作業ディレクトリを選択します。

次に関数を利用する方法です。setwd関数を利用します。

> setwd("C:/○○○/■■■/Documents/R/WorkingDirectory")
> getwd()
[1] "C:/○○○/■■■/Documents/R/WorkingDirectory"

作業ディレクトリを設定後、write.csv関数を利用して、
データフレームオブジェクトを保存します。

> write.csv(deck,file="cards.csv",row.names = FALSE)

関数を実行後、作業ディレクトリを確認してみてください。
cards.csvファイルができている事が確認できます。

今日はここまで。