[R] function problem: multi selection in one argument
Martin Maechler
m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Tue Jan 25 16:10:40 CET 2022
>>>>> Rui Barradas
>>>>> on Tue, 25 Jan 2022 14:22:47 +0000 writes:
> Hello,
> Here are 3 functions that do what the question asks for. The first 2 are
> tidyverse solutions, the last one a base R function.
> I don't understand why the group_by and mutate, that's why I've included
> a 2nd tidyverse function. And the base R function follows the same lines
> of outputing the table only without data transformation.
> And the test dataset is not iris, it only has one factor variable. It
> doesn't make sense to table a continuous variable such as Petal.Width.
> The data set mtcars has several numeric variables that are in fact
> categorical ("vs", "am") and one, "cyl", that can be tabled. The
> examples below use mtcars.
> f3 <- function(data, ...){
> groups <- unlist(list(...))
> temp <- data %>%
> select(all_of({{groups}})) %>%
> group_by(across(all_of({{groups}}))) %>%
> mutate(numbering = row_number(), max = n())
> temp %>%
> select(all_of({{groups}})) %>%
> table()
> }
> f4 <- function(data, ...){
> groups <- unlist(list(...))
> data %>%
> select(all_of({{groups}})) %>%
> table()
> }
> f5 <- function(data, ...){
> temp <- lapply(list(...), \(col) data[[col]])
> table(setNames(temp, list(...)))
> }
> f3(mtcars, "am", "cyl")
> f4(mtcars, "am", "cyl")
> f5(mtcars, "am", "cyl")
> Hope this helps,
> Rui Barradas
Thank you, Rui!
Note that your base R solution can be vastly simplified :
> f6 <- function(data, ...) table(data[, unlist(list(...))])
> f6(mtcars, "am", "cyl")
cyl
am 4 6 8
0 3 4 12
1 8 3 2
>
If you started measuring carefully, I'm sure this would not only
be the shortest but also by far the fastest solution ...
Best,
Martin
--
Martin Maechler
ETH Zurich and R Core Team
> Às 00:14 de 25/01/2022, Kai Yang via R-help escreveu:
>> Hello Team,
>> I can run the function below:
>>
>> library(tidyverse)
>>
>> f2 <- function(indata, subgrp1){
>> indata0 <- indata
>> temp <- indata0 %>% select({{subgrp1}}) %>% arrange({{subgrp1}}) %>%
>> group_by({{subgrp1}}) %>%
>> mutate(numbering =row_number(), max=max(numbering))
>> view(temp)
>> f_table <- table(temp$Species)
>> view(f_table)
>> return(f_table)
>> }
>> f2(iris, Species)
>>
>> You can see the second argument I use Species only, and it works fine.
>> But If I say, I want the 2nd argument = Petal.Width, Species , how should I write the argument? I did try f2(iris, c(Petal.Width, Species)), but I got error message:
>> Error: arrange() failed at implicit mutate() step.
>> * Problem with `mutate()` column `..1`.
>> i `..1 = c(Petal.Width, Species)`.
>> i `..1` must be size 150 or 1, not 300.
>>
>> I'm not sure how to fix the problem either in function or can fix it when using the function.
>> Thank you,
>> Kai
>> [[alternative HTML version deleted]]
>>
>> ______________________________________________
>> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
More information about the R-help
mailing list