Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 为列名传递变量?_R_Variables_Dplyr - Fatal编程技术网

R 为列名传递变量?

R 为列名传递变量?,r,variables,dplyr,R,Variables,Dplyr,例如,假设您有一个应用了一些DPLYR函数的函数,但您不能期望传递给该函数的数据集具有相同的列名 对于我的意思的简化示例,假设您有一个数据帧,arizona.trees: arizona.trees group arizona.redwoods arizona.oaks A 23 11 A 24 12 B 9 8 B 10

例如,假设您有一个应用了一些DPLYR函数的函数,但您不能期望传递给该函数的数据集具有相同的列名

对于我的意思的简化示例,假设您有一个数据帧,
arizona.trees

arizona.trees
group arizona.redwoods   arizona.oaks 
A     23                 11        
A     24                 12  
B     9                  8 
B     10                 7
C     88                 22
和另一个非常相似的数据框,
california.trees

california.trees
group    california.redwoods california.oaks 
A        25                  50        
A        11                  33  
B        90                  5 
B        77                  3
C        90                  35
您想实现一个函数,返回给定类型树的给定组(a,B,…Z)的平均值,这两个数据帧都适用

foo <- function(dataset, group1, group2, tree.type) { 
     column.name <- colnames(dataset[2])
     result <- filter(dataset, group %in% c(group1, group2) %>%
               select(group, contains(tree.type)) %>%
               group_by(group) %>%
               summarize("mean" = mean(column.name))
     return(result)
}
出于某种原因,像实现
foo()
这样的操作似乎不起作用。这可能是由于数据帧索引中出现了一些错误-函数似乎认为我试图获取
列.name
字符串的平均值,而不是检索列并将列传递给
mean()
。我不知道如何避免这种情况。有一个问题是隐式传递修改后的数据帧,该数据帧不能直接用管道操作符引用,这可能是导致该问题的原因


为什么会这样?是否有其他可行的实现方案?

我们可以使用
dplyr
的devel版本中基于
quosure
的解决方案(即将发布
0.6.0

可以针对两个数据集中的不同列测试该函数

foo1(arizona.trees, A, B, oaks)
# A tibble: 2 × 2
#  group  mean
#   <chr> <dbl>
#1     A  11.5
#2     B   7.5

foo1(arizona.trees, A, B, redwood)
# A tibble: 2 × 2
#  group  mean
#   <chr> <dbl>
#1     A  23.5
#2     B   9.5

foo1(california.trees, A, B, redwood)
# A tibble: 2 × 2
#  group  mean
#   <chr> <dbl>
#1     A  18.0
#2     B  83.5

foo1(california.trees, A, B, oaks)
# A tibble: 2 × 2
#  group  mean
#  <chr> <dbl>
#1     A  41.5
#2     B   4.0
foo1(亚利桑那州,树木,A,B,橡树)
#一个tibble:2×2
#群平均
#    
#1 A 11.5
#2 B 7.5
foo1(亚利桑那州,树木,A,B,红木)
#一个tibble:2×2
#群平均
#    
#1 A 23.5
#2 B 9.5
foo1(加州树木,A,B,红木)
#一个tibble:2×2
#群平均
#    
#1A 18.0
#2 B 83.5
foo1(加州,树木,A,B,橡树)
#一个tibble:2×2
#群平均
#   
#1 A 41.5
#2B4.0
数据
arizona.trees您必须阅读dplyr()的“非标准评估”(nse)小插曲,并注意此方法将在下一个dplyr版本中更改(),感谢您的快速回复!如果不使用devel版本的
dplyr
,就没有办法做到这一点吗?@user3450277 devel版本将很快发布为0.6.0。预计在4月,5月进入CRAN。否则,您可以使用
摘要
etc函数,但它们很快就会被弃用。如果您打算进行生产级编码,那么最好是长期编码。感谢您非常详细的回复!如果您以前没有使用过开发版本,那么安装它很容易(就像回滚到当前版本一样):
install.packages(“devtools”)#如果您没有使用过
devtools::install\u github(“tidyverse/dplyr”)
回滚只是一个普通的
install.packages(“dplyr”)
call。dev版本中的Tidyeval功能是解决问题的关键:
foo <- function(dataset, group1, group2, tree.type){
        group1 <- quo_name(enquo(group1))
         group2 <- quo_name(enquo(group2))
         colN <- rlang::parse_quosure(names(dataset)[2])
         tree.type <- quo_name(enquo(tree.type))
        dataset %>%
                filter(group %in% c(group1, group2)) %>%
                select(group, contains(tree.type)) %>%
                group_by(group) %>%
                summarise(mean = mean(UQ(colN)))
        }


foo(california.trees, A, B, redwoods)
# A tibble: 2 × 2
#  group  mean
#  <chr> <dbl>
#1     A  18.0
#2     B  83.5

foo(arizona.trees, A, B, redwoods)
# A tibble: 2 × 2
#   group  mean
#  <chr> <dbl>
#1     A  23.5
#2     B   9.5
foo1 <- function(dataset, group1, group2, tree.type){

        group1 <- quo_name(enquo(group1))
         group2 <- quo_name(enquo(group2))


         tree.type <- quo_name(enquo(tree.type))
        dataset %>%
                filter(group %in% c(group1, group2)) %>%
                select(group, contains(tree.type)) %>%
                group_by(group) %>%
                summarise_at(vars(contains(tree.type)), funs(mean = mean(.)))
        }
foo1(arizona.trees, A, B, oaks)
# A tibble: 2 × 2
#  group  mean
#   <chr> <dbl>
#1     A  11.5
#2     B   7.5

foo1(arizona.trees, A, B, redwood)
# A tibble: 2 × 2
#  group  mean
#   <chr> <dbl>
#1     A  23.5
#2     B   9.5

foo1(california.trees, A, B, redwood)
# A tibble: 2 × 2
#  group  mean
#   <chr> <dbl>
#1     A  18.0
#2     B  83.5

foo1(california.trees, A, B, oaks)
# A tibble: 2 × 2
#  group  mean
#  <chr> <dbl>
#1     A  41.5
#2     B   4.0
arizona.trees <- structure(list(group = c("A", "A", "B", "B", "C"), 
arizona.redwoods = c(23L, 
24L, 9L, 10L, 88L), arizona.oaks = c(11L, 12L, 8L, 7L, 22L)),
.Names = c("group", 
"arizona.redwoods", "arizona.oaks"), class = "data.frame",
 row.names = c(NA, -5L))

california.trees <- structure(list(group = c("A", "A", "B", "B", "C"), 
 california.redwoods = c(25L, 
11L, 90L, 77L, 90L), california.oaks = c(50L, 33L, 5L, 3L, 35L
)), .Names = c("group", "california.redwoods", "california.oaks"
), class = "data.frame", row.names = c(NA, -5L))