Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programming with measure() #4998

Closed
markfairbanks opened this issue May 14, 2021 · 5 comments
Closed

Programming with measure() #4998

markfairbanks opened this issue May 14, 2021 · 5 comments
Labels
reshape dcast melt
Milestone

Comments

@markfairbanks
Copy link

markfairbanks commented May 14, 2021

The new measure() has some very useful functionality, but the design being based around symbols makes creating custom functions with it difficult.

Simple example:

library(data.table)

df <- data.table(
  x_1 = 1,
  x_2 = 2,
  y_1 = 1,
  y_2 = 2
)

# Goal output
melt(df, measure.vars = measure(group, id, sep = "_"))
#>    group id value
#> 1:     x  1     1
#> 2:     x  2     2
#> 3:     y  1     1
#> 4:     y  2     2

my_melt <- function(data, group_name, id_name) {
  melt(
    data,
    measure.vars = measure(group_name, id_name, sep = "_")
  )
}

my_melt(df, group, id)
#>    group_name id_name value
#> 1:          x       1     1
#> 2:          x       2     2
#> 3:          y       1     1
#> 4:          y       2     2

Is there a possibility of adding an argument to measure() that is character based (or some other solution)?

In the meantime is there a recommended workaround? I think I'm missing something simple, but I couldn't figure out a good way to do this.

@tdhock
Copy link
Member

tdhock commented May 23, 2021

Hi I wrote the measure() function so I can help!
A simple easy and method is to use as.symbol and as.call,

> (measure.call <- as.call(list(
+   as.symbol("measure"),
+   as.symbol("group"),
+   as.symbol("id"),
+   sep="_")))
measure(group, id, sep = "_")
> (melt.call <- as.call(list(
+   as.symbol("melt"),
+   as.symbol("df"),
+   measure.vars=measure.call)))
melt(df, measure.vars = measure(group, id, sep = "_"))
> eval(melt.call)
   group id value
1:     x  1     1
2:     x  2     2
3:     y  1     1
4:     y  2     2
> 

As this is a straightforward use of base R I think we don't need to add an argument to measure() that is character based (or some other solution). If that is ok with you @markfairbanks can you please close?

@markfairbanks
Copy link
Author

markfairbanks commented May 23, 2021

Though this workaround works, I still think that some other solution should be implemented to make this easier. For a few reasons:

  1. As far as I know no other data.table functions require you to use as.call() or as.symbol() just to create a custom function, so it creates an inconsistency with the rest of data.table.
  2. as.call() and as.symbol() are not common functions used/understood by the vast majority of R users.
  3. All NSE functions currently in data.table have simple workarounds.
    • Ex1: setorder has setorderv (and other set*/set*v functions)
    • Ex2: [.data.table adding the env argument in v1.14.1

With those in mind here are a few proposals:

  • Add an argument that is character based to measure()
  • Add a measurev()
  • Add an env argument to measure()

@tdhock
Copy link
Member

tdhock commented May 24, 2021

Hi @markfairbanks thanks for the suggestion, please try my new measurev function in measurev branch, #5022

@tdhock tdhock added the reshape dcast melt label May 24, 2021
@mattdowle mattdowle added this to the 1.14.1 milestone May 25, 2021
@tdhock
Copy link
Member

tdhock commented May 25, 2021

well #5022 was recently merged into master so if the new measurev function works for you @markfairbanks can you please close this issue?

@markfairbanks
Copy link
Author

Works great, thanks @tdhock 👍

library(data.table)

df <- data.table(
  x_1 = 1,
  x_2 = 2,
  y_1 = 1,
  y_2 = 2
)

my_melt <- function(data, fun_list) {
  melt(
    data,
    measure.vars = measurev(fun.list = fun_list, sep = "_")
  )
}

my_melt(df, list(group = NULL, id = NULL))
#>    group id value
#> 1:     x  1     1
#> 2:     x  2     2
#> 3:     y  1     1
#> 4:     y  2     2

@jangorecki jangorecki modified the milestones: 1.14.9, 1.15.0 Oct 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reshape dcast melt
Projects
None yet
Development

No branches or pull requests

4 participants