# Rの基礎:オブジェクトによるデータの扱い ---- # DS1-resume2020-01.R # 作成:2020年05月15日,改訂: # 説明:RStudioとRの基本的な操作をコメント文(行左端が#から始まる)とその関数の形で構成されています #    読めばわかるように書いていますので,説明を読みつつ,関数を実行して結果を確認していってください # Rの基礎 ---- # Rは基本はインタプリタ # ※インタプリタ:ソースコード(スクリプト)を逐次実行可能なコード(あるいは中間表現)に変換しながら実行する方式 # 別の方式はコンパイラ:コンパイラはソースを一括変換後に実行する方式 # 一般にインタプリタはエラーのチェックがしやすい(コンパイラに比べて),その反面処理速度が遅くなりがち # Rでのデータの扱い ---- # 単独のデータ ---- # Rで扱えるデータの型:数値,文字,文字列(日本語も一応可能) # 変数はデータを格納できる入れ物で,命令や関数で利用可能 # aという変数に数値3を代入しろという命令 # 半角の「=」は右辺を左辺に代入する記号(演算子)で,右辺と左辺が等しいという意味ではない a=3 # なおRStudioでは変数などの使用状況がEnvironment画面で確認できる(aが変数(Values)に追加されているはず) # 文字列は必ずダブルクオーテーションかシングルクォーテーションで囲む # 重要:仮に文字列で囲まないとしたの例では「阪神」という変数を意味する b="阪神" # あるいは b='阪神' # 複数の命令を1行に書くときはセミコロンで区切る # 重要:セミコロンとコロンを区別すること(意味が異なる) a=3; b=4; a+b; # なおRでは既に値が代入されている変数に別の値を代入しても警告なしに置き換わる # 上の変数bの例(最初は「阪神」という文字列,その後で数値4) # 上記の記述と次の直接計算は同じ結果 3+4 # 1行1命令の時はセミコロンは省略可能 # ※なお代入の記号 = は <- でもよい(昔はこっちしか使えなかった) a<-3 # どうしても左辺を右辺に代入したければ,->を使う 3->a # Rでは命令が文法的にまだ入力途中の段階でEnterキーを押して改行しても実行されない # 続きを入力するように,行の先頭のプロンプトが半角の「+」に変化する # ※間違って途中で改行してしまった(Enterキーを押してしまった)場合は気にせず次の行に続きを書けばよい # Tips:1つの命令が長くなるときは,わざと意味のある切れ目で改行して入力する方が見やすい a+ b # また半角の空白も無視される(ただし文字列として扱っている場合を除く) a + b # 変数は代入されたデータにより型(数値や文字列など)を自動判別してくれるので,特に利用者が定義する必要はない # 変数に入っている値の確認は変数名を入力してEnterキーを押せばよい a # 変数の型を調べるためには関数 typeof(), mode(), class() を使えばよい typeof(a) # オブジェクトの詳細なデータ型 mode(a) # オフジェクトのデータ型の表示と変換 class(a) # オブジェクトのクラスの型(属性) # Tips:ちなみにオブジェクトは変数や先で出てくるベクトル,配列,関数などの総称 # 複数のデータをまとめて扱う方法 ---- # ベクトル:1次元の連続データの場合 ---- # ベクトルは同じ種類の変数を共通の名前と添え字でひとまとめにしたもの # ※通常の変数が一戸建ての住宅とすると,ベクトルは長屋 # 例えば1から10を10個の変数に代入 a1=1; a2=2; a3=3; a4=4; a5=5; a6=6; a7=7; a8=8; a9=9; a10=10; # めっちゃだるいだけでなく,計算上の使い勝手も悪い # 代わりにc()という関数を利用する #※関数とは何らかの計算をしてくれる処理に名称をつけたもの.Rで用意してくれているものあるし,自分で作ることも可能 # 先の回で実際に作ってもらいます a=c(1,2,3,4,5,6,7,8,9,10); # ましになったけど,まだだるい b=c(1:10) # ※連続する値の場合,最初の値,半角のコロン,最後の値で指定できる # Tips:関数の()の中の値は「引数(ひきすう)」,関数を実行するときに関数にオブジェクトを渡すことができる # ベクトルの各要素を使うときは変数名[添字](下の例は3番目の要素を表示) # ベクトルの各要素が添字で利用できることの恩恵は先のところで出てくる b[3] # ベクトルの長さを調べるときは length() を利用する # 調べたいオブジェクトを引数として与える length(b) # 規則性のあるデータの作り方 ---- # 連続でなくて例えば3おきのデータを作りたいときには seq() を用いるとよい # ただし開始する値,終了する値,間隔などを名前付き引数としてそれぞれ指定する(from, to, by) seq(from=1, to=10, by=3) # なお 名前付き引数のfrom, to, by は省略して次のように書いても同じ結果となる # 重要:できるだけ省略せず名前付き引数として書いてください(間違いが少なくなります) seq(1, 10, 3) # 繰り返しのあるデータを作りたいときは rep() を用いるとよい rep(c(1,4,2), times=3) # 引数としてtimesを使用すると,1つめの引数が指定された回数反復される(この場合は3回反復) rep(c(1,4,2), each=3) # 引数としてeachを使用すると,1つ目の引数がベクトルなど複数の値がある場合は, # それぞれ同じものが反復されて次の値が反復(この場合は3回ずつ順に反復) rep(c(1,4,2), len=7) # 引数としてlenを使用すると,1つめの引数を長さが7になるように反復 # 2つめの引数を単に数字だけで与えると times= として解釈される rep(c(1,4,2), 3) # 複数のオブジェクト型が混在するデータの場合 ---- # リスト型は文字と数値を混在させることが可能 # c() ではなく,list() を利用する # リスト内の個々の値の取り出しはベクトルと同じ形式 # ベクトルやリストの引数で連続する範囲を指定するときは半角コロンが使用できる # 不連続で複数の要素を表示したい場合は c()を使えばよい d=list(6, "Kanemoto", "Tomoaki") d[1] d[2:3] d[c(1,3)] # 多次元のデータの場合 ---- # 行列 ---- # 多次元のデータは行列あるいは配列として扱う # 行列は2次元配列と同じ # 行列を生成するためには関数 matrix() を用いる # 引数の1つ目は行列に使用するデータ,nrowは行数,ncolは列数 matrix(1:10, nrow=5, ncol=2, byrow=F) # 5行×2列の配列となる. # byrowは使用するデータをどのように配列に並べるかの指定(行優先の指定) # byrow=F とすると,数値は1列目,2列目の順に配置される matrix(1:10, nrow=5, ncol=2, byrow=T) # byrow=T とすると1行目,2行目,…という順に配置される matrix(1:10, nrow=5, ncol=2, byrow=T, dimnames=list(LETTERS[1:5],LETTERS[25:26])) # dimnamesを使うと行と列の名前を定義できる # 名前はlist形式で,まず行で次に列の順序 # なお LETTERS は英大文字のベクトル.添え字はは1から26 LETTERS[1] # 行列の各要素を表示する方法は行あるいは列で範囲を指定したいものを書けばよい e=matrix(1:10, nrow=5, ncol=2, byrow=T) e e[1,2] # 特定の要素 e[,2] # 特定の列の要素 e[3,] # 特定の行の要素 e[1:3,] # 特定の複数行の要素 e[c(1,4),] # 連続しない複数行の要素 # ベクトルやリストを利用しても行列は定義できる f=matrix(list(1,"阪神","タイガース",2,"広島","カープ"), nrow=2, ncol=3, byrow=T) f # dimnames() の引数として行列を指定して,行と列の名前を後から定義(変更)することも可能 # Tips:後から行や列の名前を変更するときに便利 dimnames(f)=list(list("あ","い"),list("う","え","お")) f # 配列 ---- # 2次元データは配列を生成する array() を使っても定義できる array(1:10, dim=c(5,2), dimnames=list(LETTERS[1:5],LETTERS[25:26])) # ただし byrow=F に固定される # 3次元以上のデータは配列で dim で各次元の最大要素数を指定すればよい array(1:8, dim=c(3,3,3), dimnames=list(LETTERS[1:3],LETTERS[8:10],LETTERS[24:26])) # dim() を使うとベクトルを多次元化できる # 重要:dim() で変換する対象の変数のデータの個数が右辺で指定された次元の要素数の倍数でないとエラーを起こす f=1:9 dim(f)=c(3,3) # エラーなし g=1:8 dim(g)=c(3,3) # エラーとなる # データフレーム ---- # データフレームは列ごとに異なる型のデータを取ることができて,行方向に1つのまとまりを持つような # データの型である # 表計算ソフトでデータを集計しているのをイメージするとわかりやすいかもしれない # Excelのようなデータの取り扱いはデータフレームを使うとよい(それゆえ,よく使います) # 例えば学生の成績を例にすると,1列目が名前(文字型),2列目が素点(数値型),3列目が評価(文字型) # 学生として岡田,真弓,和田,金本で,素点がそれぞれ90, 40, 60, 70.評価は秀,不可,可,良とする # これをデータフレームとして作成するときには data.frame() を用いればよい h=data.frame(NAME=c("岡田","真弓","和田","金本"), SCORE=c(90,40,60,70), GRADE=c("秀","不可","可","良")) # NAMEやSCOREなどが列名になる # なお列名には日本語も使用可能.列名はダブルクオテーションやシングルクォーテーションで囲んではダメ # 列ごとのデータを取り出すときは,データフレーム名$列名,行ごとのデータを取り出すときは行列と同じ h$NAME h[,2] # 列名を後から変更したいときは colnames() を利用する colnames(h)=c("名前", "素点", "評価") h colnames(h)=c("NAME", "SCORE", "GRADE") #後の例が動かなくなるので元に戻す h # データフレームの行に名前をつけたいときは row.names を利用する h=data.frame(NAME=c("岡田","真弓","和田","金本"), SCORE=c(90,40,60,70), GRADE=c("秀","不可","可","良"), row.names=c("岡田","真弓","和田","金本")) h # あるいは h=data.frame(NAME=c("岡田","真弓","和田","金本"), SCORE=c(90,40,60,70), GRADE=c("秀","不可","可","良")) h # 一旦行の名前を消した row.names(h)=c("岡田","真弓","和田","金本") h # データフレームは order() を使って並べ替えもできる h[order(h$SCORE),] order(h$SCORE) # 降順(大きいものから小さいものの順)に並べ替えるときは次のとおり h[order(-h$SCORE),] order(-h$SCORE) # order()の正体は行の順番のベクトルを作成している # 自分の好みの順序で並べたいなら c() で指定すればよい h[c(3,4,1,2),] # データ型の調べ方と変換 ---- # すでに説明したようにオブジェクトのデータ型やクラスを調べるためのコマンドとして次のようなものがある typeof(a) # オブジェクトの詳細なデータ型 mode(a) # オフジェクトのデータ型の表示と変換 class(a) # オブジェクトのクラスの型(属性) # このうち typeof() と mode() はオブジェクトの要素の型を,また class() はオブジェクトの所属するクラス,つまり属性の型を表示する # クラスの型が定義されていない場合は,要素の型がそのまま使われる(以下の例で確認) mode(3) class(3) # なおnumeric型の場合はデータストレージ型としてdoubleとintegerが設定されていて typeof() により確認できる # 整数の後ろに L を追加すると整数型(integer)になる(何もつけないと実数型のdoubleになる) mode(3); typeof(3) mode(3L); typeof(3L) # データ型を調べる他のコマンドとしては is.データ型() の形の関数が用意されている is.numeric(3) is.character(3) # これらのコマンドは調べる型に引数が一致していると TRUE,不一致だと FALSEを返す # TRUE や FALSE は論理型と呼ばれる(先の回で説明します) # またあるデータ型のオブジェクトを別のデータ型に変換するコマンドとして as.データ型() のコマンドがある as.integer(3) is.double(as.integer(3)) # なおデータ型の変換は引数として与えるオブジェクトが正しくないとエラーが起こる as.character(3) as.numeric("a")