Rは変数とシンボルを介してオブジェクトを参照するらしいが...

f:id:ts0818:20210207163152p:plain

yukawanet.com

涙腺崩壊と言う言葉があるように、涙が溢れて目が壊れそうな状況をそのように表現します。しかし実際には涙腺が崩壊することはなく、あくまで涙が溢れ出てくるだけではありますが、そんな涙、流すだけではなく、しっかりそれらを受け止める器官があることをご存知でしょうか。つまり排水溝です。

人体の神秘、涙腺崩壊後の涙を排出する「穴」がまぶたに存在、海外で衝撃走る | 秒刊SUNDAY

⇧ 何てこった...

確かに、激震が走りましたな、どうもボクです。

というわけで、Rについてです。

レッツトライ~。 

 

Rは「データ型」と「データ構造」を考える必要がある?

「R」ってインタプリタ言語だし、変数を宣言する時に「データ型」を指定しない動的型付け言語でもあるから、変数に入ってる「データ型」って何なのか調べたいこと、あるあるだよね?

え?ないですか?

そこは、嘘でも、あるあるって言うところでしょうが~!

はい、取り乱しました。

で、「R」ってのは、

www.researchgate.net

Figure 1. Data structures in R, commonly used in the package 'Luminescence'. The colour and the shape of individual objects indicate similar data types (e.g. logical, integer, character) whereas their alignment represents the structure. Code under each structure definition corresponds to the creation of the structures in R. From left to right structures increase in complexity: scalar, vector, matrix, data frame, list. For further data structures and information cf. Crawley (2012).

https://www.researchgate.net/publication/249961022_A_practical_guide_to_the_R_package_Luminescence

⇧ 上記サイト様によると、

  • データ型(data types)
  • データ構造(the structure)

の2つは別々のものってことになりますと。

実際どうなってるのか?

cran.r-project.org

In every computer language variables provide a means of accessing the data stored in memory. R does not provide direct access to the computer’s memory but rather provides a number of specialized data structures we will refer to as objects. These objects are referred to through symbols or variables. In R, however, the symbols are themselves objects and can be manipulated in the same way as any other object. This is different from many other languages and has wide ranging effects.

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Objects

⇧「変数」と「シンボル」 を介して「オブジェクト」を参照するって言ってるんだけど、「シンボル」自体も「オブジェクト」でできてるんだそうな...

と言うか、

objects are often coerced to different types during computations. There are also many functions available to perform explicit coercion. When programming in the R language the type of an object generally doesn’t affect the computations, however, when dealing with foreign languages or the operating system it is often necessary to ensure that an object is of the correct type.

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Objects

⇧ ってなことを言ってる割には、

The R specific function typeof returns the type of an R object. Note that in the C code underlying R, all objects are pointers to a structure with typedef SEXPREC; the different R data types are represented in C by SEXPTYPE, which determines how the information in the various parts of the structure is used.

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Objects

⇧「データ型」についての説明が曖昧模糊としてるような...

いや「C言語」のコードに依存してるってのは分かったけど、「typeof」ってメソッドで確認できるのが、「R」における「データ型」の全量ってことで良いんだよね?

「typeof」ってメソッドで確認できるのが、「データ型」と仮定して矛盾しないとした場合、ドキュメント(https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Objects)によると以下が「データ型」の全量らしい。

データ型 内容
NULL NULL
symbol a variable name
pairlist a pairlist object (mainly internal)
closure a function
environment an environment
promise an object used to implement lazy evaluation
language an R language construct
special an internal function that does not evaluate its arguments
builtin an internal function that evaluates its arguments
char a ‘scalar’ string object (internal only) ***
logical a vector containing logical values
integer a vector containing integer values
double a vector containing real values
complex a vector containing complex values
character a vector containing character values
... the special variable length argument ***
any a special type that matches all types: there are no objects of this type
expression an expression object
list a list
bytecode byte code (internal only) ***
externalptr an external pointer object
weakref a weak reference object
raw a vector containing bytes
S4 an S4 object which is not a simple object

⇧ で、内容についての捕捉が以下になる模様。

Users cannot easily get hold of objects of types marked with a ‘***’.

Function mode gives information about the mode of an object in the sense of Becker, Chambers & Wilks (1988), and is more compatible with other implementations of the S language. Finally, the function storage.mode returns the storage mode of its argument in the sense of Becker et al. (1988). It is generally used when calling functions written in another language, such as C or FORTRAN, to ensure that R objects have the data type expected by the routine being called. (In the S language, vectors with integer or real values are both of mode "numeric", so their storage modes need to be distinguished.)

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Objects

> x <- 1:3
> typeof(x)
[1] "integer"
> mode(x)
[1] "numeric"
> storage.mode(x)
[1] "integer"

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Objects

⇧ ってな感じで「typeof」以外にも、

  • mode
    more compatible with other implementations of the S language
  • storage mode
    generally used when calling functions written in another language, such as C or FORTRAN, to ensure that R objects have the data type expected by the routine being called. (In the S language, vectors with integer or real values are both of mode "numeric", so their storage modes need to be distinguished.)

「mode」と「storage mode」 を使い分けろ、ってなことを言ってるみたい...

stackoverflowの発言を見ると、

stackoverflow.com

typeof is the key function.

The others are variations of typeof that exist solely for the purpose of S compatibilty and are mostly not used today.

storage.mode can be used in S when call calling .Fortran or .C with numeric data so you know whether an input is an integer or double, say. This distinction can often be blurred in R but when passing objects to these languages the distinction is important. It is like typeof in this respect. mode just gives numeric for both of these so it is coarser.

> mode(1L)
[1] "numeric"
> storage.mode(1L)
[1] "integer"

> mode(1)
[1] "numeric"
> storage.mode(1)
[1] "double"

https://stackoverflow.com/questions/36794744/what-is-the-difference-in-terms-of-idea-of-mode-storage-mode-typeof-in-r

⇧ 今日においては、「typeof」以外を使うことは無いだろう、ってことらしい。

話が脱線しましたが、

vector」「matrix」「data frame」「list」ってのは「データ構造」になるかと思いきや「データ型」に「list」が入ってるやん?

って感じで、「type」って定義がかなりカオスなドキュメントの「R」なんだけど、 

objects are often coerced to different types during computations. There are also many functions available to perform explicit coercion. When programming in the R language the type of an object generally doesn’t affect the computations, however, when dealing with foreign languages or the operating system it is often necessary to ensure that an object is of the correct type.

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Objects

⇧ Rオブジェクトは計算中に様々な「types」に強制変換されることがあるため、正しい「type」であることを確認することが大事って言っていて、

  • Basic types
  • Attributes
  • Special compound objects

の3つをいきなり羅列してくれてるわけなんですが、この3つが様々な「types」の実例ってことなんですかね?

まぁ、この3つの中に、「vector」「matrix」「data frame」「list」とか出てくるんだけども、結局のところ「R」での「type」の定義がハッキリしない...

あと、「symbol」の説明が分かり辛い...

Symbols refer to R objects. The name of any R object is usually a symbol. Symbols can be created through the functions as.name and quote.

Symbols have mode "name", storage mode "symbol", and type "symbol". They can be coerced to and from character strings using as.character and as.nameThey naturally appear as atoms of parsed expressions, try e.g. 

as.list(quote(x + y)).

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Symbol-objects

⇧「R」のすべてのオブジェクトの名前が通常は「symbol」ということなんですが、

実施する関数 戻り値
mode name
storage mode symbol 
typeof symbol 

ってな感じで、「name」と「symbol」 の値を取り得るけど、

  • as.character
  • as.name

のどっちかを使って「文字列型」に強制変換できます、ってことみたいなんだけど、例が「as.list(quote(x + y)).」しかないから、何が言いたかったのかよく分からん...

「R」のドキュメントを全て熟読すれば何かが分かるのかも知らんけど、少なくともドキュメントをサラッと読んだ感じでは、明確に「データ型」「データ構造」っていう分類をしてるかっていう点は読み取れなくて、すべてはオブジェクトである、ってことだけは分かった感じです。

まぁ、このあたりは、有識者の方がまとめてくださるのを待ちますかね。

 

Rの「ベクトル型」にはnames属性があるらしいんだが...

まぁ、長々と「R」の「データ型」について調べてたきたんだけども、そもそも、何て言うか、事の発端は、「cooks.distance()」ってメソッドで返される値の「データ型」何なのか?って気になって、試しに、以下を実施して調べたところ、カオス過ぎてWhat’s?ってなったので。(コード実施したときは、「R」のドキュメントの存在を知らず、ネットのブログなどの情報のみを信じてました)

ちなみに、データを読み込む際は、「RStudio」で「Session」>「Set Working Deirectory」>「Choose Directory」で読み込むファイルのあるディレクトリを指定する必要がある模様。

■cosmetics_company_analysis.R

# データの読み込み
cosmetics <- read.csv("cosmetics_company_sales.csv")

Y_data <- subset(cosmetics, Brand == "Y")
Y_data <- Y_data[, colnames(Y_data) !="Brand"]
rownames(Y_data) <- c(1:nrow(Y_data))

# データの中身
cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5]

# データ型の確認
typeof(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
mode(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
class(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])

# データ構造の確認
is.vector(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
length(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])

# name属性
names(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])

■実行結果(「Console」の内容)

> # データの読み込み
> cosmetics <- read.csv("cosmetics_company_sales.csv")
> Y_data <- subset(cosmetics, Brand == "Y")
> Y_data <- Y_data[, colnames(Y_data) !="Brand"]
> rownames(Y_data) <- c(1:nrow(Y_data))
> lm_Y <- lm(sales~. -CustomerID, data=Y_data)
> # データの中身
> cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5]
        172         483         634         707        1011 
  3.4164570   0.8134450   1.3978587   0.5084253 310.7283839 
       1020        1096        1423        1533        1581 
  0.5090091   1.5785982  20.4658988 624.8265934   1.9540456 
> # データ型の確認
> typeof(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
[1] "double"
> mode(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
[1] "numeric"
> class(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
[1] "numeric"
> # データ構造の確認
> is.vector(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
[1] TRUE
> length(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
[1] 10
> names(cooks.distance(lm_Y)[cooks.distance(lm_Y) > 0.5])
 [1] "172"  "483"  "634"  "707"  "1011" "1020" "1096" "1423"
 [9] "1533" "1581"

⇧ ってな感じで、データ型の確認で返ってきた結果が「double型」「numeric型」って統一されていないのにも混乱したのですが、データの中身を見た感じ、何か、「key: value」みたいな感じの構造になってるから、Javaで言うところの「Map」みたいな構造のデータ型ってことかいな?「R」だと何になるんだろう?って思っておったら、まさかの「vector型」になってるというね。

ネットで、「R ベクトル型」とかでググっても、「vector型」のデータの中身で「key」っぽいものを持ってるケースってのが出てこない...

What's?

試しに「R ベクトル型 key」で検索したら、ヒットしましたよ「names属性」。

ベクトルには names 属性と呼ばれる属性情報を付けることが出来,要素の名前を持つベクトルは名前を使って要素を取り出すことが出来る.

http://cse.naro.affrc.go.jp/takezawa/r-tips/r/26.html

⇧ 上記サイト様によりますと、「vector型」に「names属性」が付与できるらしいですと。

「R」のドキュメントによると、

All objects except NULL can have one or more attributes attached to them. Attributes are stored as a pairlist where all elements are named, but should be thought of as a set of name=value pairs. A listing of the attributes can be obtained using attributes and set by attributes<-individual components are accessed using attr and attr<-.

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Attributes

⇧「NULL」以外のオブジェクトに対して「attributes」ってものが付与できるって言ってるんだけど、「attributes」が何なのかについては、説明はないんだけど、

Attributes are used to implement the class structure used in R. If an object has a class attribute then that attribute will be examined during evaluation. The class structure in R is described in detail in Object-oriented programming.

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Attributes

⇧「Rで使用されるクラス構造の実装」のために使用されるってことらしい。

「R」における「クラス」について、詳しくは、「Object-oriented programming.」の章を見てね、ってことらしい。

話が脱線しましたが、「names属性」は、

names attribute, when present, labels the individual elements of a vector or list. When an object is printed the names attribute, when present, is used to label the elements. The names attribute can also be used for indexing purposes, for example, quantile(x)["25%"].

One may get and set the names using names and names<- constructions. The latter will perform the necessary consistency checks to ensure that the names attribute has the proper type and length.

Pairlists and one-dimensional arrays are treated specially. For pairlist objects, a virtual names attribute is used; the names attribute is really constructed from the tags of the list components. For one-dimensional arrays the names attribute really accesses dimnames[[1]].

https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Names

⇧ ってな感じで、「vector型」や「list型」の要素に対して「labels」を提供しますよって感じで、逆に言うと、「names属性」を付与してあげないと、「vector型」や「list型」は「key: value」みたいな構造のデータにできないってことみたいね。

まぁ、「R」の独自仕様ということですが、知らんがな...

ちなみに、「Console」で、以下のように入力して「Enterキー」押下すると「Help」に内容が表示されるんだけど、

?[調べたい内容]

f:id:ts0818:20210207130618p:plain

⇧ 残念ながら、どんな値を返すかとかについては記載がないんですな...

このあたり、

my-log-pll97u88.hatenablog.com

⇧ 追求されてる方がおりました。

「R」について思ったことは、Pythonの時も思ったんだけど、ドキュメントで「戻り値」を明示して欲しいよね... 

まぁ、何が言いたいかと言うと、JavaAPIドキュメントみたいに「戻り値」の記載があるようなドキュメントが欲しいよね...

毎回、モヤモヤ感が半端ない...

結局、「変数」と「シンボル」の使い分けもよく分からんかったし...

2021年2月8日(月)追記:↓ ここから

ちなみに、クラスのオブジェクトの中身とかは、

kasuya.ecology1.org

lmの結果は以下のようにres1に入れておきます

> res1<-lm(y1~x1)

res1の中味を関数str()で見ます。

> str(res1)

lm()が返す結果オブジェクトの中味

⇧ 上記サイト様によりますと、

str(object)

⇧ って感じで確認できるみたいですね。

2021年2月8日(月)追記:↑ ここまで

 

今回はこのへんで。