R语言中,mode和class有何区别

Python07

R语言中,mode和class有何区别,第1张

1、对象类属性的不同

首先,mode和typeof可以归为一个类别,class是另外一个类别。mode和typeof描述的是数据在内存中的存储类型;class描述的是对象的类属性,因为历史的原因更新过好多次,前身是S语言,所以R语言中数据对象的存储类型变化过好多次。

2、精确度的不同

mode和storage.mode得到的是一种比较古老的类型,来自于S语言,其中storage.mode比mode要更精确mode(3L)#numericstorage.mode(3L)#integertypeof是一种最新的查看类型的函数,针对于R语言而非S语言,而且更为精确,更为细致。

对于指定类属性的数据对象,class和oldClass的结果是一样的a=data.frame(1:10)oldClass(a)#"data.frame"class(a)#"data.frame"但是如果没有指定数据对象的类属性,那么oldClass返回NULL,而class会根据数据对象的存储类型(type)与维度属性来自动给出一个类属性。

3、表示方式的不同

mode:表示对象在内存中的存储类型,基本数据类型'atomic'mode:numeric(Integer/double),complex,character和logical,递归的对象(recursiveobject):'list'或'function'。

class:是一种抽象类型,或者理解为一种数据结构(数据框,因子,列表),他主要是用来给泛型函数(参考java中泛型的概念)识别参数用。所以当给函数传参数的时候如果发生错误,就查看class属性。

作者:任坤

链接:https://www.zhihu.com/question/24908785/answer/29404778

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

R中的 . 符号只是个普通字符,可以在符号名称中出现,下面几种情况中 . 具有特殊含义:

1. 一个 environment 中以 . 开头的变量默认被当作隐藏变量,用 ls.str() 不会被列出来,除非 ls.str(all.names = TRUE) .

2. 一些函数中 . 具有特殊的意义,比如线性模型函数 lm() 的 formula 参数中的 . 符号会被特殊解读,比如 lm(mpg ~ ., data = mtcars) 中 mpg ~ . 这个formula会被lm()解读成在mtcars数据表中以mpg为被解释变量,其他列为解释变量做线性回归模型,在变量很多的情况下可以简化代码,但风险是数据列变化时回归方程也跟着变,有些类似于SQL中使用 select * 的风险。

3. 不同的函数可能让 . 拥有不同的含义,比如dplyr::do()函数中的 . 就是指每个数据行,而magrittr::`%>%`右侧函数参数中出现的 . 是指符号左边的对象,pipeR::`%>>%`右侧表达式中的 . 是指符号左边的对象,rlist::list.map() 函数 expr 参数中的 . 被解读成 implicit lambda expression,表示需要映射的list中的每个元素本身。

4. (感谢

@王雨晨

的回答,差点遗忘了对于R来说最关键的一点).符号被专门用来实现R中一个比较简单的面向对象系统S3的method dispatch,即可以用UseMethod()定义一个方法xyz,那么xyz.class这指xyz方法对于class类型的实现。这种S3面向对象系统比较简单,也容易发生混淆,比如head.data.frame实际上是head对于data.frame类型的实现,但也可以定义head.data方法,然后定义一种frame类型,这样在代码中就会发生混淆。

总而言之,. 符号在一般的变量中只是一个普通符号而已,只不过有些函数用 . 提供特殊用法方便书写或引用,或者用作S3系统中分隔方法与类的字符。

=== 补充 1 ===

R中访问对象中的元素有多种情况,一类是取子集(subsetting),用 [] ,比如一个 list(a=1,b=2) ["a"] 获得 list(a=1),该运算对list, vector等对象有定义,对environment没有定义;还有一类是取元素(extracting),用 [[ ]] ,list(a=1, b=2) [["a"]] 获得元素值 1,这种情况也可以用 $ 来取元素,该计算对于environment有定义,但$对vector无定义。另外还有S4对象,需要用@ 符号来访问slot,背后对应的函数是slot()函数,不过这些也不是定死的,对于自己定义的对象总可以去自己实现 "[", "[[", "$" 等方法来定义如何计算,可以参见我的 renkun-ken/pipeR @ GitHub 扩展包中Pipe对象的 $.Pipe() (pipeR/pipe.R at master · renkun-ken/pipeR · GitHub),就可以动态生成 closure 实现仿佛 jQuery 或者 C# LINQ 一样的以对象为基础的管道操作。