kittygirl
kittygirl

Reputation: 2443

no applicable method for 'tbl_vars' applied to an object of class "c('fseq', 'function')" when use R pipe

In this SO post,
iris %>% left_join(iris %>% group_by(Species) %>% summarise(N=n())) is part of answer.

I translate this script to: iris %>% {left_join(.,. %>% group_by(Species) %>% summarise(N=n()))},but got error:

Error in UseMethod("tbl_vars") : 
  no applicable method for 'tbl_vars' applied to an object of class "c('fseq', 'function')"

I think 2 script are equal,what cause the error?

Upvotes: 2

Views: 2232

Answers (3)

akrun
akrun

Reputation: 887501

We can do this more directly in creating a column with add_count

library(dplyr)
iris %>%
      add_count(Species)

If we are using the %>%, it is recommended not to make it overly cumbersome with inserting {} inside the flow, instead it can be

iris %>% 
     group_by(Species) %>%  # grouping done
     summarise(N = n()) %>%  # get summarised count
     right_join(iris, .)  # right or left join

This chain makes it easier to understand. As others have noted, there is a way to do this by wrapping it containerized in {}, however, IMHO that would also defeat the whole purpose of chaining.

Upvotes: 1

Cole
Cole

Reputation: 11255

This may be an issue with as it seems like it evaluates the .%>% ... sequence to something else:

library(dplyr)

iris %>%
    left_join({
        print(. %>%
                  mutate(new = 5L))
    },
    copy = TRUE)
#> Functional sequence with the following components:
#> 
#>  1. mutate(., new = 5L)
#> 
#> Use 'functions' to extract the individual functions.
#> Error in as.data.frame.default(y): cannot coerce class 'c("fseq", "function")' to a data.frame

You may want to report the issue to Github or I can follow-up with it on Github - not sure if this is more or . I used to use similar pipes. As @duck notes, it appears wrapping {.} around the dot escapes whatever is happening.

iris %>%
    {
        {.}%>%
            group_by(Species)%>%
            summarize(N = n())
    }

Also... the inevitable data.table alternative:

library(data.table)
dt = as.data.table(iris)
dt[, N := .N, by = Species]
dt
#>      Sepal.Length Sepal.Width Petal.Length Petal.Width   Species  N
#>   1:          5.1         3.5          1.4         0.2    setosa 50
#>   2:          4.9         3.0          1.4         0.2    setosa 50
#>   3:          4.7         3.2          1.3         0.2    setosa 50
#>   4:          4.6         3.1          1.5         0.2    setosa 50
#>   5:          5.0         3.6          1.4         0.2    setosa 50
#>  ---                                                               
#> 146:          6.7         3.0          5.2         2.3 virginica 50
#> 147:          6.3         2.5          5.0         1.9 virginica 50
#> 148:          6.5         3.0          5.2         2.0 virginica 50
#> 149:          6.2         3.4          5.4         2.3 virginica 50
#> 150:          5.9         3.0          5.1         1.8 virginica 50

Upvotes: 1

Duck
Duck

Reputation: 39613

Try this Kitty:

iris %>% left_join(x = ., y = {.} %>% group_by(Species) %>% summarise(N=n()))

Upvotes: 1

Related Questions