14.关于select()

【上一篇:13.关于arrange()】
【下一篇:15.关于mutate()】

    select()函数用来选择数据框的列。重申:filter()函数用来根据列的值选择行,arrange()函数用来根据列的值对行进行排序。
    ?select之后看到title是"Subset columns using their names and types",也就是根据列名和类型对列取子集。
    以前你学习数据框的时候是如何对选择数据框的列的呢?

flights[,c("year","month","day")]
flights[,1:3]

    select()函数完全可以替代以上写法。两者的区别在哪里呢?(好吧,现在脑子是懵的,姑且认为select()有可以和其他很多函数连用,省去了自己写子函数筛选的麻烦吧。)

#根据列名选择,一列
> select(flights,year)
#一个变量名写重了,也只会输出一个,不像直接flights[,c("year","year")]
> select(flights,year,year)
# A tibble: 336,776 x 1
    year
   <int>
 1  2013
 2  2013
 3  2013
 4  2013
 5  2013
 6  2013
 7  2013
 8  2013
 9  2013
10  2013
# ... with 336,766 more rows
> flights[,c("year","year")]
# A tibble: 336,776 x 2
    year  year
   <int> <int>
 1  2013  2013
 2  2013  2013
 3  2013  2013
 4  2013  2013
 5  2013  2013
 6  2013  2013
 7  2013  2013
 8  2013  2013
 9  2013  2013
10  2013  2013
# ... with 336,766 more rows

#变量名的顺序会影响输出结果中变量名显示的顺序
> select(flights,year,month)
> select(flights,month,year)
#这点和flights[,c("year","month")]、flights[,c("month","year")]是一样的

#根据列名选择,多列
> select(flights,year,month,day)
> select(flights,year|month|day)
> select(flights,1:3)
> select(flights,year:day)
> select(flights,c(year,month,day))
> select(flights,c("year","month","day"))
###小结
# 与filter()和arrange()函数不同,从第二个参数开始,“逗号”分割的变量名或表达式是"与"的关系
# filter()函数会筛选出同时满足所有条件的行
# arrange()函数会先按照第二个参数排序,第三个会进一步改变前面排序的结果,第四个会改变前两步排序的结果,依次类推
# select()函数中,从第二个参数开始,“逗号”分割的变量名或表达式是“或”的关系
# 这里提到了两个在select()函数中应用的操作符:“:”和"c()"
# 和向量的使用方法有点像
# 不要记所有写法,够用就行,少的列,直接逗号枚举,多的连续的列用“:”
# 用数字,好吧,列少且知道你想要那几列的时候最适合不过了。

#反选
> select(flights,-year)
> select(flights,!year)
> select(flights,-year,-month,-day)
> select(flights,-(year:day))
> select(flights,!(year:day))
###小结:
# 这里也提到两种在select()函数中使用的操作符:"!"和"-"
# !和-在这里都是取反的意思(或者说取补集),基于上面正选的方法加个取反符号就可以。

#筛选包含"time"同时以"time"开头的列
> select(flights,contains("time") & starts_with("time"))
###小结:
# 这里的&也是应用在select()函数中的一个操作符,表示“和”的关系

#用starts_with()函数多选
> select(flights,starts_with("dep"))
> select(flights,starts_with("dep"),starts_with("arr"))
#用ends_with()函数多选
> select(flights,ends_with("time"))
#用contains()函数多选
> select(flights,contains("time"))
#用matches()函数多选
> select(flights,matches("time"))
#用num_range()函数多选,num_range()函数执行后产生字符串向量c("dep_time","dep_delay")
> select(flights,num_range("dep_",c("time","delay")))

    starts_with(),ends_with(),contains(),matches(),num_range()这些函数是select()函数中的一类通过匹配变量名中的模式("模式匹配")来选择列的函数,这些函数必须要和select函数连用才行,单独的这些函数是不会发生作用的(只是本人的猜测,也许不正确)。其帮助文档见:

starts_with(match, ignore.case = TRUE, vars = NULL)
ends_with(match, ignore.case = TRUE, vars = NULL)
contains(match, ignore.case = TRUE, vars = NULL)
matches(match, ignore.case = TRUE, perl = FALSE, vars = NULL)
num_range(prefix, range, width = NULL, vars = NULL)

#注意哦,ignore.case默认是忽略大小写的,要根据自己的需要更改呀!

    还有一类函数可以指定特定的列,也需要和select()函数连用才行,他们是everything()和last_col(),其帮助文档如下:

#选择所有变量
everything(vars = NULL)
#选择最后一个变量
last_col(offset = 0L, vars = NULL)

vars是一个字符串向量,offset是位移量。
这两个函数的工作原理没有弄很清楚,其实真的不知道select(flights,everything())这样写一遍有啥意义。
先看他们的经典应用场景吧:
# 用everything()函数将某些变量移动到数据框的最前面
# 在调整数据框列的顺序的时候应该特别有用
> select(flights, time_hour, air_time, everything())
# A tibble: 336,776 x 19
   time_hour           air_time  year month   day dep_time sched_dep_time
   <dttm>                 <dbl> <int> <int> <int>    <int>          <int>
 1 2013-01-01 05:00:00      227  2013     1     1      517            515
 2 2013-01-01 05:00:00      227  2013     1     1      533            529
 3 2013-01-01 05:00:00      160  2013     1     1      542            540
 4 2013-01-01 05:00:00      183  2013     1     1      544            545
 5 2013-01-01 06:00:00      116  2013     1     1      554            600
 6 2013-01-01 05:00:00      150  2013     1     1      554            558
 7 2013-01-01 06:00:00      158  2013     1     1      555            600
 8 2013-01-01 06:00:00       53  2013     1     1      557            600
 9 2013-01-01 06:00:00      140  2013     1     1      557            600
10 2013-01-01 06:00:00      138  2013     1     1      558            600
# ... with 336,766 more rows, and 12 more variables: dep_delay <dbl>,
#   arr_time <int>, sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
#   flight <int>, tailnum <chr>, origin <chr>, dest <chr>, distance <dbl>,
#   hour <dbl>, minute <dbl>

# 选择数据框的最后一列
# 这个就好像更容易理解一些,更实用一些
> select(flights,last_col())
# A tibble: 336,776 x 1
   time_hour          
   <dttm>             
 1 2013-01-01 05:00:00
 2 2013-01-01 05:00:00
 3 2013-01-01 05:00:00
 4 2013-01-01 05:00:00
 5 2013-01-01 06:00:00
 6 2013-01-01 05:00:00
 7 2013-01-01 06:00:00
 8 2013-01-01 06:00:00
 9 2013-01-01 06:00:00
10 2013-01-01 06:00:00
# ... with 336,766 more rows

下面两种写法是一样的效果:
> select(flights,2:last_col(5))
> select(flights,day:last_col(5))
#这里2:last_col(5)表示取第二个变量到(从后数第5个变量之前的列)

    第三列函数是通过字符串向量选择列的,包括all_of()、any_of()、where(),其帮助文档:

#将x向量中的列提取出来,如果数据框中没有这样的列名,则会报错。所以说条件严格
all_of(x)
#与all_of()一样,但是如果数据框中没有这样的列名,也不会报错,条件宽松
any_of(x, ..., vars = NULL)
例如:
x<-c("month","day")
select(flights,all_of(x))
select(flights,any_of(x))
# x是一个字符串向量或表示列位置的数字向量
# vars是一个向量,不提供的话会直接从上下文中找

where()函数是个新大陆,它的参数是一个函数:where(fn),fn这个函数的返回值必须是一个TRUE或FLASE的向量,最后会保留TRUE的列,例如:
#如下命令,先将数据框的列名(即所有变量,是一个向量)传递给is.numeric()函数,函数执行后返回一个逻辑向量。
> select(flights,where(is.numeric))
# A tibble: 336,776 x 14
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ... with 336,766 more rows, and 6 more variables: arr_delay <dbl>,
#   flight <int>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>

    select()函数的可以实现对变量的重命名,参数格式为new_name = old_name:

> flights
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ... with 336,766 more rows, and 11 more variables: arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#   time_hour <dttm>
> select(flights,month_new = month)
# A tibble: 336,776 x 1
   month_new
       <int>
 1         1
 2         1
 3         1
 4         1
 5         1
 6         1
 7         1
 8         1
 9         1
10         1
# ... with 336,766 more rows

## 执行后你会发现,并不如你想象的只改变month列的名字,它还把其他列都弄没了。
##所以,用rename()函数会更好:
> rename(flights,month_new = month)
# A tibble: 336,776 x 19
    year month_new   day dep_time sched_dep_time dep_delay arr_time
   <int>     <int> <int>    <int>          <int>     <dbl>    <int>
 1  2013         1     1      517            515         2      830
 2  2013         1     1      533            529         4      850
 3  2013         1     1      542            540         2      923
 4  2013         1     1      544            545        -1     1004
 5  2013         1     1      554            600        -6      812
 6  2013         1     1      554            558        -4      740
 7  2013         1     1      555            600        -5      913
 8  2013         1     1      557            600        -3      709
 9  2013         1     1      557            600        -3      838
10  2013         1     1      558            600        -2      753
# ... with 336,766 more rows, and 12 more variables: sched_arr_time <int>,
#   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

【上一篇:13.关于arrange()】
【下一篇:15.关于mutate()】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容