R语言入门秘录10/25:根据位置从数据框中选择列

数据分析网整理自tbkken的《R语言入门25招》,一招招技能带你走进R语言。

问题

根据数据的位置从数据框中选取出若干列。

解决方案

选择一列数据的操作如下:

代码

dfrm[[n]]

这会返回一列数据,即dfrm中的第n列。

要从数据框中选择多列数据并将其包装成新的数据框,用下面的的表达式:

代码

dfrm[n]

这会返回一个仅仅由dfrm的第n列数据构成的数据框。

代码

dfrm[ c(n1, n2,……,nk) ]

这会返回由dfrm的n1、n2、……、nk列构成的数据框。还可以用矩阵下标风格的方式选择一列或多列数据:

代码

dfrm[, n]

返回的是第n列(假设n只含有一个数值)。

代码

dfrm[, c(n1, n2, …, nk)]

返回的是由n1, n2,…, nk列构成的数据框。

注意,根据你选择的是一列还是多列,矩阵下标风格可以返回两种数据类型(单列或数据框)。

讨论

有很多从数据框中选择列的方法。在你弄明白这其中的逻辑关系之前,你肯定是一头雾水。在你阅读下面的解释时,要注意语法上的细微变化,例如一个逗号,一个双括号之类的小玩意对表达式含义的影响。

然我们来摆弄一下芝加哥地区16个大城市的人口数据:

代码

> suburbs

city county state pop

1 Chicago Cook IL 2853114

2 Kenosha Kenosha WI 90352

3 Aurora Kane IL 171782

4 Elgin Kane IL 94487

5 Gary Lake(IN) IN 102746

6 Joliet Kendall IL 106221

7 Naperville DuPage IL 147779

8 Arlington Heights Cook IL 76031

9 Bolingbrook Will IL 70834

10 Cicero Cook IL 72616

11 Evanston Cook IL 74239

12 Hammond Lake(IN) IN 83048

13 Palatine Cook IL 67232

14 Schaumburg Cook IL 75386

15 Skokie Cook IL 63348

16 Waukegan Lake(IL) IL 91452

用列表的概念可以精确的选中某一列,比如选择第一列:

代码

> suburbs[[1]]

[1] “Chicago” “Kenosha””Aurora” “Elgin”

[5] “Gary” “Joliet””Naperville” “Arlington Heights”

[9] “Bolingbrook””Cicero” “Evanston” “Hammond”

[13] “Palatine””Schaumburg” “Skokie” “Waukegan”

suburbs的第一列是一个向量,所以suburbs[[1]]返回的就是一个向量。如果第一列是一个因子,那我们得到的就是因子。

如果使用单方括号的话,结果就会有些变化了,例如suburbs[1]或suburbs[ c(1,3) ]。得到的依然是所选择的列,但R会将其中的数据包装秤一个数据框。下面的例子返回的第一列就包装在数据框中:

代码

> suburbs[1]

city

1 Chicago

2 Kenosha

3 Aurora

4 Elgin

5 Gary

6 Joliet

7 Naperville

8 Arlington Heights

9 Bolingbrook

10 Cicero

11 Evanston

12 Hammond

13 Palatine

14 Schaumburg

15 Skokie

16 Waukegan

接下来的例子会以数据框的形式返回第一和第三列:

代码

> suburbs[ c(1,4) ]

city pop

1 Chicago 2853114

2 Kenosha 90352

3 Aurora 171782

4 Elgin 94487

5 Gary 102746

6 Joliet 106221

7 Naperville 147779

8 Arlington Heights 76031

9 Bolingbrook 70834

10 Cicero 72616

11 Evanston 74239

12 Hammond 83048

13 Palatine 67232

14 Schaumburg 75386

15 Skokie 63348

16 Waukegan 91452

容易让人困惑的一个重要原因就是suburbs[[1]]和suburbs[1]的差别很小,但两者的结果却大相径庭:

代码

1

suburbs[[1]]

返回的是一列数据。

代码

suburbs[1]

这返回的是一个数据框,其中只有一列数据。这其实是dfrm[ c(n1,n2,…,nk)]的一个特例。因为这里只有一个数字,所以不需要用到c(…)。

这里的关键是“一列数据”跟“包含一列数据的一个数据框”是不一样的。第一个表达式返回的是一列数据,是一个向量或因子;第二个表达式返回的是一个数据框,这是不一样的。

在R中还可以用矩阵的概念选择列,我们在解决方案中已经演示过。这里要强调一个比较奇怪的特性:你可能得到的是一列数据,也有可能得到一个数据框,这取决于你用了多少下标。最简单的情况是只有一个下标,那么得到就是一列数据,比如:

代码

> suburbs[,1]

[1] “Chicago” “Kenosha””Aurora” “Elgin”

[5] “Gary” “Joliet””Naperville” “Arlington Heights”

[9] “Bolingbrook””Cicero” “Evanston” “Hammond”

[13] “Palatine””Schaumburg” “Skokie” “Waukegan”

如果是按照矩阵下标的风格使用多个多下标,返回的就是一个数据框:

代码

> suburbs[,c(1,4)]

city pop

1 Chicago 2853114

2 Kenosha 90352

3 Aurora 171782

4 Elgin 94487

5 Gary 102746

6 Joliet 106221

7 Naperville 147779

8 Arlington Heights 76031

9 Bolingbrook 70834

10 Cicero 72616

11 Evanston 74239

12 Hammond 83048

13 Palatine 67232

14 Schaumburg 75386

15 Skokie 63348

16 Waukegan 91452

这导致了一个问题。加入你在老式的R脚本中看到下面这样的表达式:

代码

dfrm[,vec]

这返回的是一列数据还是一个数据框?好吧,这取决于具体情况。如果vec中只含有一个值,得到的就是一列数据;否则,就会得到一个数据框。仅仅从这个语法形式是无法判断最终结果的。

为了避免这个问题,可以在下标中加入drop=FALSE;这强制R将返回的结果转换成数据框:

代码

dfrm[,vec,drop=FALSE]

现在返回的数据结构就不会再模棱两可了,一定会是一个数据框。

总而言之,用矩阵下标从数据框中选择列并不是一个好办法。我建议用前面说到的列表操作符代替这种方式。功能完全一样,但要更加简洁明了。

我以前一直以为这些操作返回的数据类型是一样的,经常为此而在矩阵、向量、数据框之间不断地做强制转换,这下才恍然大悟了。R里面的诡异规则还不少啊。

本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「我们」留言处理。

(0)
小胖的头像小胖编辑
上一篇 2016-01-03 13:47
下一篇 2016-01-05 13:55

相关文章

关注我们
关注我们
分享本页
返回顶部