R 中 select 列的规范方式
Canonical way to select columns in R
我正在比较 dplyr 和 "plain R" 中常见的 "tidying" 操作(请参阅 output here and source here 了解我的意思)。
我很难找到一种 "canonical" 和简洁的 方法来 select 仅使用变量名的列(按规范,我的意思是,纯普通R 并且对于任何对 R 了解最少的人来说都很容易理解(所以没有 "voodoo trick"))。
示例:
## subset: all columns from "var_1" to "var_2" excluding "var_3"
## dplyr:
table %>% select(var_1:var_2, -var_3)
## plain R:
r <- sapply(c("var_1", "var_2", "var_3"), function(x) which(names(table)==x))
table[ ,setdiff(r[1]:r[2],r[3]) ]
有什么改进纯 R 语法的建议吗?
编辑
我实施了一些建议并比较了不同语法的性能,并注意到 match
和 subset
的使用导致性能意外下降:
# plain R, v1
system.time(for (i in 1:100) {
r <- sapply(c("size", "country"), function(x) which(names(cran_df)==x))
cran_df[,r[1]:r[2]] } )
## user system elapsed
## 0.006 0.000 0.007
# plain R, using match
system.time(for (i in 1:100) {
r <- match(c("size", "country"), names(cran_df))
cran_df[,r[1]:r[2]] %>% head(n=3) } )
## user system elapsed
## 0.056 0.028 0.084
# plain R, using match and subset
system.time(for (i in 1:100) {
r <- match(c("size", "country"), names(cran_df))
subset(cran_df, select=r[1]:r[2]) %>% head(n=3) } )
## user system elapsed
## 11.556 1.057 12.640
# dplyr
system.time(for (i in 1:100) select(cran_tbl_df,size:country))
## user system elapsed
## 0.034 0.000 0.034
看起来 subset
的实现不是最理想的...
您可以使用内置的 subset
函数,它可以接受一个 select
参数,该参数遵循与 dplyr::select
相似(但不完全相同)的语法。请注意,删除列必须在第二步完成:
t1 <- subset(table, select = var1:var2)
t2 <- subset(t1, select = -var_3)
或:
subset(subset(table, select = var1:var2), select = -var_3)
例如:
subset(subset(mtcars, select = c(mpg:wt)), select = -hp)
我正在比较 dplyr 和 "plain R" 中常见的 "tidying" 操作(请参阅 output here and source here 了解我的意思)。
我很难找到一种 "canonical" 和简洁的 方法来 select 仅使用变量名的列(按规范,我的意思是,纯普通R 并且对于任何对 R 了解最少的人来说都很容易理解(所以没有 "voodoo trick"))。
示例:
## subset: all columns from "var_1" to "var_2" excluding "var_3"
## dplyr:
table %>% select(var_1:var_2, -var_3)
## plain R:
r <- sapply(c("var_1", "var_2", "var_3"), function(x) which(names(table)==x))
table[ ,setdiff(r[1]:r[2],r[3]) ]
有什么改进纯 R 语法的建议吗?
编辑
我实施了一些建议并比较了不同语法的性能,并注意到 match
和 subset
的使用导致性能意外下降:
# plain R, v1
system.time(for (i in 1:100) {
r <- sapply(c("size", "country"), function(x) which(names(cran_df)==x))
cran_df[,r[1]:r[2]] } )
## user system elapsed
## 0.006 0.000 0.007
# plain R, using match
system.time(for (i in 1:100) {
r <- match(c("size", "country"), names(cran_df))
cran_df[,r[1]:r[2]] %>% head(n=3) } )
## user system elapsed
## 0.056 0.028 0.084
# plain R, using match and subset
system.time(for (i in 1:100) {
r <- match(c("size", "country"), names(cran_df))
subset(cran_df, select=r[1]:r[2]) %>% head(n=3) } )
## user system elapsed
## 11.556 1.057 12.640
# dplyr
system.time(for (i in 1:100) select(cran_tbl_df,size:country))
## user system elapsed
## 0.034 0.000 0.034
看起来 subset
的实现不是最理想的...
您可以使用内置的 subset
函数,它可以接受一个 select
参数,该参数遵循与 dplyr::select
相似(但不完全相同)的语法。请注意,删除列必须在第二步完成:
t1 <- subset(table, select = var1:var2)
t2 <- subset(t1, select = -var_3)
或:
subset(subset(table, select = var1:var2), select = -var_3)
例如:
subset(subset(mtcars, select = c(mpg:wt)), select = -hp)