R中的子集选取运算符

作者:张光耀,硕士研究生,现就读于中科院心理所,

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
[11
a[[1]]
[11


可以看出,执行 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]])
[121.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]])
[1TRUE


当设置成 drop = FALSE, 即默认设置时,输出类型仍为列表,但是设置为 drop = TRUE 时,输出类型变成了double了,即只是列表的内容。

不同数据类型,简化和保留的转换也是不同的:

R中的子集选取运算符

对于所有的数据类型,保留的结果是相同的,可以得到与输入相同类型的输出,但是不同类型属觉得简化却有不同。

原子向量:去除名字。

x = c(a=1, b=2)
x[1]

1 
x[[1]]
[11


列表:返回列表中的对象,而不是一个元素列表。

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]
[11 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:21 2


3

$ 运算符

<$> 是一个简写运算符,这里 x$y 等价于 x[[“y”, exact = FALSE。通常用来访问数据框中的变量。例如 mtcars$mpg。

使用 <$> 的最常见的错误是,你知道数据框某一列的名字,但是这个名字储存在一个变量中,如果 <$> 后面不使用列的名字而是使用变量的名字就会出错。

x = "mpg"
mtcars$x
NULL


<$> 和 <[[ ]]> 之间的不同是,前者是部分匹配。

head(mtcars$mp)
[121.0 21.0 22.8 21.4 18.7 18.1
head(mtcars[["mp"]])
NULL


如果想要避免这类情况发生,可以将全局变量 warnPartialMatchDollar 设置为TRUE,但是可能影响其他代码的执行,特别是加载了一些包之后。

总的来说,<[ ]> 选取后的数据类型与原数据类型相同,<[[ ]]> 选取后的数据类型会发生变化,它输出的是列表的内容,<$> 是多用于选取和引用数据框中数据的部分匹配的运算符。根据具体的情况(是编程还是分析数据,以及有些函数在输入类型上的限制)选取适合的引用形式,会帮助读者更高效的达到目的。

本文主要参考了哈德利·威克汉姆所著《高级R语言编程指南》第三章第二节内容。


- END -


往期精彩:


R中的子集选取运算符


R中的子集选取运算符

公众号后台回复关键字即可学习

回复 爬虫             爬虫三大案例实战  
回复 
Python        1小时破冰入门

回复 数据挖掘      R语言入门及数据挖掘
回复 
人工智能      三个月入门人工智能
回复 数据分析师   数据分析师成长之路 
回复 机器学习      机器学习的商业应用
回复 数据科学      数据科学实战
回复 常用算法      常用数据挖掘算法

给我【好看】

你也越好看!

R中的子集选取运算符

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-11-05
  • 2021-11-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-28
  • 2021-05-19
猜你喜欢
  • 2021-11-08
  • 2021-11-27
  • 2021-06-17
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案