为什么我使用SE或NSE dplyr函数得到不同的结果

时间:2015-08-13 14:53:35

标签: r dplyr standard-evaluation

当我通过lazyeval包使用标准评估时,我得到了dplyr函数的不同结果。

以下是如何使用250k行和约230k组重现与我的实际数据相近的内容。我想按id1,id2进行分组,并为每个组设置max(datetime)的行。

library(dplyr)
# random datetime generation function by Dirk Eddelbuettel
# http://stackoverflow.com/questions/14720983/efficiently-generate-a-random-sample-of-times-and-dates-between-two-dates
rand.datetime <- function(N, st = "2012/01/01", et = "2015/08/13") {
  st <- as.POSIXct(as.Date(st))
  et <- as.POSIXct(as.Date(et))
  dt <- as.numeric(difftime(et,st,unit="sec"))
  ev <- sort(runif(N, 0, dt))
  rt <- st + ev
}

set.seed(42)
# Creating 230000 ids couples
ids <- data_frame(id1 = stringi::stri_rand_strings(23e4, 9, pattern = "[0-9]"), 
                  id2 = stringi::stri_rand_strings(23e4, 9, pattern = "[0-9]"))
# Repeating randomly the ids[1:2000, ] to create groups    
ids <- rbind(ids, ids[sample(1:2000, 20000, replace = TRUE), ])
datas <- mutate(ids, datetime = rand.datetime(25e4))

当我使用NSE方式时,我得到230000行

df1 <- 
  datas %>% 
  group_by(id1, id2) %>% 
  filter(datetime == max(datetime))
nrow(df1) #230000

但是当我使用SE时,我只获得了229977行

ids <- c("id1", "id2")
filterVar <- "datetime"
filterFun <- "max"
df2 <- 
  datas %>% 
  group_by_(ids) %>% 
  filter_(.dots = lazyeval::interp(~var == fun(var), 
                                   var = as.name(filterVar), 
                                   fun = as.name(filterFun)))
nrow(df2) #229977

我的两段代码是对的吗? 为什么我会遇到不同的结果?感谢。

1 个答案:

答案 0 :(得分:1)

在提供列名称向量时,您需要在echo "I eat $(cat poo.txt)" 中指定.dots参数。

group_by_

当你没有指定df2 <- datas %>% group_by_(.dots = ids) %>% filter_(.dots = lazyeval::interp(~var == fun(var), var = as.name(filterVar), fun = as.name(filterFun))) nrow(df2) [1] 230000 参数时,看起来group_by_可能会将向量中的第一个列名称作为唯一的分组变量。您可以通过仅在.dots上进行分组来检查此内容。

id1

(如果您只在df1 <- datas %>% group_by(id1) %>% filter(datetime == max(datetime)) nrow(df1) [1] 229977 上分组,则行数为229976)。