Dplyr 0.3.0.9000 How to use do () correctly

I tried to reproduce the result on the SO question: dplyr: How to apply do () to the group_by result?

Here are the data

person = c('Grace', 'Grace', 'Grace', 'Rob', 'Rob', 'Rob') foods = c('apple', 'banana', 'cucumber', 'spaghetti', 'cucumber', 'banana') eaten <- data.frame(person, foods, stringsAsFactors = FALSE) 

The result that I tried to reproduce is as follows:

 [[1]] [,1] [,2] [,3] [1,] "apple" "apple" "banana" [2,] "banana" "cucumber" "cucumber" [[2]] [,1] [,2] [,3] [1,] "spaghetti" "spaghetti" "cucumber" [2,] "cucumber" "banana" "banana" 

The source code creating the result above, as below, no longer works:

 > eaten %>% group_by(person) %>% do(function(x) combn(x$foods, m = 2)) Error: Results are not data frames at positions: 1, 2 

I tried several ways to use the do () function to no avail.

 > eaten %>% group_by(person) %>% do(combn(.$foods, m = 2)) Error: Results are not data frames at positions: 1, 2 > eaten %>% group_by(person) %>% do(.$foods, combn, m =2) Error: Arguments to do() must either be all named or all unnamed > eaten %>% group_by(person) %>% do((combn(.$foods, m=2))) Error: Results are not data frames at positions: 1, 2 

Only one below seems to work with a warning:

 > eaten %>% group_by(person) %>% do(as.data.frame(combn(.$foods, m = 2))) # person V1 V2 V3 # 1 Grace apple apple banana # 2 Grace banana cucumber cucumber # 3 Rob spaghetti spaghetti cucumber # 4 Rob cucumber banana banana # Warning messages: # 1: In rbind_all(out[[1]]) : Unequal factor levels: coercing to character # 2: In rbind_all(out[[1]]) : Unequal factor levels: coercing to character 

Believe me, there should be a change in the behavior of do () in the new version. What are the changes? What is the correct idiom / way of using do ()? Thanks.

EDIT: the last dplyr is installed and run the code suggested by @hadley

 packageVersion("dplyr") [1] '0.3.0.2' eaten %>% group_by(person) %>% do(x = combn(.$foods, m = 2)) # Source: local data frame [2 x 2] # Groups: <by row> # # person x # 1 Grace <chr[2,3]> # 2 Rob <chr[2,3]> 

EDIT2: need to extract column "x" as suggested by @hadley

 eaten2 <- eaten %>% group_by(person) %>% do(x = combn(.$foods, m = 2)) eaten2[["x"]] # [[1]] # [,1] [,2] [,3] # [1,] "apple" "apple" "banana" # [2,] "banana" "cucumber" "cucumber" # # [[2]] # [,1] [,2] [,3] # [1,] "spaghetti" "spaghetti" "cucumber" # [2,] "cucumber" "banana" "banana" 
+6
source share
2 answers

Move EDIT2 to Q to answer to close the question:

For the latest dplyr 0.3.0.2+, you need to extract the "x" column, as suggested by @hadley

 eaten2 <- eaten %>% group_by(person) %>% do(x = combn(.$foods, m = 2)) eaten2[["x"]] # [[1]] # [,1] [,2] [,3] # [1,] "apple" "apple" "banana" # [2,] "banana" "cucumber" "cucumber" # # [[2]] # [,1] [,2] [,3] # [1,] "spaghetti" "spaghetti" "cucumber" # [2,] "cucumber" "banana" "banana 
+2
source

Obviously, this is a matter of preference / what data is needed for, but I think one of the above possibilities is really smart for creating a convenient and accurate data frame. Using tidyr::gather , I feel that it returns an object that clarifies who ate what food, without extracting anything.

 person = c( 'Grace', 'Grace', 'Grace', 'Rob', 'Rob', 'Rob' ) foods = c( 'apple', 'banana', 'cucumber', 'spaghetti', 'cucumber', 'banana' ) eaten <- data.frame(person, foods, stringsAsFactors = FALSE) eaten %>% group_by(person) %>% do(as.data.frame(combn(.$foods, m = 2))) %>% gather(meal, foods, -1) 

is returning

 # Groups: person [2] person meal foods <chr> <chr> <chr> 1 Grace V1 apple 2 Grace V1 banana 3 Rob V1 spaghetti 4 Rob V1 cucumber 5 Grace V2 apple 6 Grace V2 cucumber 7 Rob V2 spaghetti 8 Rob V2 banana 9 Grace V3 banana 10 Grace V3 cucumber 11 Rob V3 cucumber 12 Rob V3 banana > 
0
source

Source: https://habr.com/ru/post/1204549/


All Articles