作者: 张光耀 ,硕士研究生,现就读于中科院心理所,
GitHub 主页: https://github.com/usplos
前言
R中的子集选区运算符主要包括<[ ]>,<[[ ]]>,<$>三种。其中<[ ]> 和 <[[ ]]> 相似,但是前者返回的是列表,后者返回的是列表中的内容。<$> 运算符与选定的字符串一起就成为 <[[ ]]> 的缩写。
1
[ ] 与 [[ ]]
如果只想获取对象内的内容而不想让内容再以相同的对象类型输出时,应该使用 <[[ ]]>,这是因为当时用 <[ ]> 时,总是与原来相同的数据类型输出。要获取内容,就需要使用 <[[ ]]>.
有这样一句话可以很好地帮助读者理解两者之间的区别。
“如果把列表 x 看成装载对象(货物)的火车,那 x[[5]] 就是5号车厢中的对象(货物),而 x[4:6] 就是火车的第4-6号车厢” ——@RLangTip
<[[ ]]>必须和一个正整数或者字符串一起使用才能达到返回内容的目的。
a=list(a=1,b=2)
a[1]
$a
[1] 1
a[[1]]
[1] 1
可以看出,执行 a[1],返回的是第一个列表。而执行 a[[1]],返回的是名第一个列表中的内容。
因为数据框也是一种列表,因此也可以用 <[[ ]]> 来提取一列。下面以 mtcars 数据为例,比较一下两种提取有何不同。
x=mtcars[1]
head(x)
mpg
Mazda RX4 21.0
Mazda RX4 Wag 21.0
Datsun 710 22.8
Hornet 4 Drive 21.4
Hornet Sportabout 18.7
Valiant 18.1
head(mtcars[[1]])
[1] 21.0 21.0 22.8 21.4 18.7 18.1
执行 mtcars[1],产生的仍然是一个数据框,它只是返回了只包含第一列数据框。而执行 head(mtcars[[1]]),产生只是第一列中的数据。可以进一步考察他们的类型。
typeof(mtcars[1])
[1] "list"
typeof(mtcars[[1]])
[1] "double"
mtcars[1] 产生的类型仍然是一个列表,而 mtcars[[1]] 产生的类型就成了 double 了。
2
简化与保留
在子集选取时,一定要注意最后产生的是什么类型的数据,是否仍保持着原来的数据结构,因为在交互式数据分析时,应尽可能将选组的数据保持尽量简单的数据结构,而对于另一些情况,比如编程,希望选取的子集尽量保持一致的变量类型。
在对矩阵和数据框进行子集选取的时候,通常会省略 drop = FALSE, 导致很多错误,可以看一下这个条件设置不同时数据输出的类型。
typeof(mtcars[, 1, drop = FALSE])
[1] "list"
typeof(mtcars[, 1, drop = TRUE])
[1] "double"
typeof(mtcars[, 1, drop = TRUE]) == typeof(mtcars[[1]])
[1] TRUE
当设置成 drop = FALSE, 即默认设置时,输出类型仍为列表,但是设置为 drop = TRUE 时,输出类型变成了double了,即只是列表的内容。
不同数据类型,简化和保留的转换也是不同的:
对于所有的数据类型,保留的结果是相同的,可以得到与输入相同类型的输出,但是不同类型属觉得简化却有不同。
原子向量:去除名字。
x = c(a=1, b=2)
x[1]
a
1
x[[1]]
[1] 1
列表:返回列表中的对象,而不是一个元素列表。
y = list(a=1, b=2)
str(y[1])
List of 1
$ a: num 1
str(y[[1]])
num 1
因子:扔掉所有不同的水平。
z = factor(c("a", "b", "c"))
z[1]
[1] a
Levels: a b c
z[1, drop = T]
[1] a
Levels: a
矩阵或者数组:抛弃所有长度为1的维度。
a = matrix(1:9, nrow=3)
a[1, , drop = FALSE]
[,1] [,2] [,3]
[1,] 1 4 7
a[1, , drop = TRUE]
[1] 1 4 7
数据框:如果仅输出一列,返回一个向量而不是数据框
df = data.frame(a = 1:2, b = c(2,4))
str(df[1])
'data.frame': 2 obs. of 1 variable:
$ a: int 1 2
str(df[[1]])
int [1:2] 1 2
str(df[ , "a", drop = FALSE])
'data.frame': 2 obs. of 1 variable:
$ a: int 1 2
str(df[ , "a", drop=TRUE])
int [1:2] 1 2
3
$ 运算符
<$> 是一个简写运算符,这里 x$y 等价于 x[[“y”, exact = FALSE。通常用来访问数据框中的变量。例如 mtcars$mpg。
使用 <$> 的最常见的错误是,你知道数据框某一列的名字,但是这个名字储存在一个变量中,如果 <$> 后面不使用列的名字而是使用变量的名字就会出错。
x = "mpg"
mtcars$x
NULL
<$> 和 <[[ ]]> 之间的不同是,前者是部分匹配。
head(mtcars$mp)
[1] 21.0 21.0 22.8 21.4 18.7 18.1
head(mtcars[["mp"]])
NULL
如果想要避免这类情况发生,可以将全局变量 warnPartialMatchDollar 设置为TRUE,但是可能影响其他代码的执行,特别是加载了一些包之后。
总的来说,<[ ]> 选取后的数据类型与原数据类型相同,<[[ ]]> 选取后的数据类型会发生变化,它输出的是列表的内容,<$> 是多用于选取和引用数据框中数据的部分匹配的运算符。根据具体的情况(是编程还是分析数据,以及有些函数在输入类型上的限制)选取适合的引用形式,会帮助读者更高效的达到目的。
参
考
本文主要参考了哈德利·威克汉姆所著《高级R语言编程指南》第三章第二节内容。
- END -
往期精彩:
公众号后台回复关键字即可学习
回复 爬虫 爬虫三大案例实战
Python
1小时破冰入门
回复 数据挖掘 R语言入门及数据挖掘
回复 人工智能 三个月入门人工智能
回复 数据分析师 数据分析师成长之路
回复 机器学习 机器学习的商业应用
回复 数据科学 数据科学实战
常用算法
常用数据挖掘算法
本文由R语言中文社区 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 【 数据集合】并集、交集、差集、子集
- 微服务不是全部,只是特定领域的子集
- 常用算法思想之动态规划的区间子集思想
- 算法 - 找出数组中子集乘积的最大值
- Python编程实现从字典中提取子集的方法分析
- 再谈中文字体的子集化与动态创建字体
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。