这个问题适合于理解group_by函数的正确功能。
假设我有一个包含5个二进制变量的数据帧(这些变量的含义并不重要)和一个代表某些用户的变量id。例如:
id<- c("A","A" , "B" , "B")
d<- as.data.frame(id)
d$d1<- c(1,0,1,0)
d$d2<- c(1,0,1,0)
d$d3<- c(0,1,1,0)
d$d4<- c(0,1,0,1)
d$d5<- c(0,1,0,0)
> d
id d1 d2 d3 d4 d5
1 A 1 1 0 0 0
2 A 0 0 1 1 1
3 B 1 1 1 0 0
4 B 0 0 0 1 0
我将构建一个能够检查每个用户A和B的函数,变量d1到d5在所有用户中都包含1。
verificator<- function(d )
{
r<- prod(apply(d[,2:6],2, sum))
r<- as.logical(r)
return(r)
}
例如,对于A用户,对于每个d1到d5,所有这些中都有第一个。
verificator(d[1:2,])
[1] TRUE
但是,对于B用户,我们有
verificator(d[3:4,])
[1] FALSE
当我使用dplyr函数来评估d矩阵时,出现了错误:
d2<- d %>% group_by(id) %>% summarise(one = verificator(.))
d2
Source: local data frame [2 x 2]
id one
1 A TRUE
2 B TRUE
为什么B用户返回TRUE?
答案 0 :(得分:3)
如果我们需要获得预期的输出,一个选项是
d %>%
group_by(id) %>%
summarise_each(funs(sum)) %>% rowwise() %>%
do(data.frame(id = .[1L], one = as.logical(prod(unlist(.[-1])))))
# id one
# <fctr> <lgl>
#1 A TRUE
#2 B FALSE
我们也可以使用by
base R
来执行此操作
verificator <- function(x){
as.logical(prod(colSums(x)))
}
c(by(d[-1], d$id, FUN = verificator))
# A B
#TRUE FALSE
答案 1 :(得分:2)
您得到错误结果的原因是,当使用%>%
时,点(.
)代表%>%
左侧表达式的竞争结果。因此,您只需在完整数据框verificator()
上评估d
两次。
您可以看到以下内容。首先,我检查应用于完整数据框的verificator()
是否确实返回TRUE
:
verificator(d)
## [1] TRUE
然后,我定义了verificator()
的另一个变体,用于打印其参数:
verificator_p <- function(d) {
print(d)
return(verificator(d))
}
使用您提出的代码,表明它始终是传递给函数的完整数据框:
d %>% group_by(id) %>% summarise(one = verificator_p(.))
## Source: local data frame [4 x 6]
## Groups: id [2]
##
## id d1 d2 d3 d4 d5
## (fctr) (dbl) (dbl) (dbl) (dbl) (dbl)
## 1 A 1 1 0 0 0
## 2 A 0 0 1 1 1
## 3 B 1 1 1 0 0
## 4 B 0 0 0 1 0
## Source: local data frame [4 x 6]
## Groups: id [2]
##
## id d1 d2 d3 d4 d5
## (fctr) (dbl) (dbl) (dbl) (dbl) (dbl)
## 1 A 1 1 0 0 0
## 2 A 0 0 1 1 1
## 3 B 1 1 1 0 0
## 4 B 0 0 0 1 0
## Source: local data frame [4 x 6]
## Groups: id [2]
##
## id d1 d2 d3 d4 d5
## (fctr) (dbl) (dbl) (dbl) (dbl) (dbl)
## 1 A 1 1 0 0 0
## 2 A 0 0 1 1 1
## 3 B 1 1 1 0 0
## 4 B 0 0 0 1 0
## Source: local data frame [2 x 2]
##
## id one
## (fctr) (lgl)
## 1 A TRUE
## 2 B TRUE
我承认不知道的是,为什么d
被打印三次而不是两次......