richfitz / remake

Make-like declarative workflows in R
Other
340 stars 32 forks source link

YAML fields: yes/no in addition to TRUE/FALSE #88

Open wlandau opened 8 years ago

wlandau commented 8 years ago

Sometimes I find myself wanting to use yaml::as.yaml to generate a remake file. As far as I know, it's fairly common to use "yes" and "no" in YAML for logicals. Apparently in keeping with this convention, as.yaml replaces TRUE with yes and FALSE with no. This causes a little friction with remake. If I have code.R below

generate_data = function(){
  data(mtcars)
  write.csv(mtcars, file = "data.csv")
}

process_data = function(filename){
  d = read.csv(filename)
  data.frame(x = d$mpg, y = d$cyl)
}

myplot = function(data){
  plot(y~x, data = data)
}

and remake.yml

sources:
  - code.R

targets:
  all:
    depends: plot.pdf

  data.csv:
    command: generate_data()

  processed:
    command: process_data("data.csv")

  plot.pdf:
    command: myplot(processed)
    plot: TRUE

then remake::make works. Next, I tried feeding remake.yml through yaml::as.yaml to create remake2.yml.

library(yaml)
lines = readLines("remake.yml")
string = paste(lines, collapse = "\n")
y = yaml.load(string)
write(as.yaml(y), "remake2.yml")

The new file remake2.yml has a line with "plot: yes" rather than "plot: TRUE", which remake doesn't like.

> library(remake)
> make(remake_file = "remake2.yml")
[  LOAD ] 
Error in generators[[type]](name, dat$command, dat$opts, extra) : 
  While processing target 'plot.pdf':
    Unknown plot_options 'yes' in target 'plot.pdf'
> 
richfitz commented 8 years ago

Thanks - I agree this seems unfortunate. I can look at expanding the boolean hook to support yes/no. The issue is you start getting a lot of really weird bugs with the permissive nature of what yaml parsers by default convert to boolean (y/n, t/f are the really bad ones).

wlandau commented 8 years ago

That would be great if it's not too messy. Making as.yaml write TRUE/FALSE might be easier, so as you can see, I submitted a yaml package issue.

richfitz commented 7 years ago

Any thoughts on this @krlmlr?

krlmlr commented 7 years ago

@wlandau: How about walking the list and replacing all constant logicals with their character equivalents?

I'm not sure remake should be any more permissive. But we need robust conversion yaml <-> R object, and remake could provide an interface for that.

richfitz commented 7 years ago

So, the yaml::yaml.load function provides support for handlers which we use to avoid things like t, f, n and y being interpreted as logicals, but there is no corresponding easy hook in yaml::as.yaml. But we could implement @krlmlr's suggestion and then export to_yaml/from_yaml functions that try to be symmetric.

wlandau commented 7 years ago

@krlmlr I think that would definitely be progress, assuming to_yaml / from_yaml would be able to wrangle all those character equivalents after the fact. I would love to learn how remake works internally, fork it, and make a pull request, but I'm just starting an intense new job, so it's unlikely that I'll have the chance in the foreseeable future.

jwhendy commented 7 years ago

Any update on this? I'm using yaml to specify x/y/z coordinates and need them named as that when I write the file. Imagine my surprise when I 1) found this awesome package and 2) looked at the output to see things like:

position:
     x: -0.712
     'TRUE': 0.194
     z: 0.124
richfitz commented 7 years ago

For generating we are limited by the yaml package - this issue here is the relevant one: https://github.com/viking/r-yaml/issues/30

jwhendy commented 7 years ago

Whoops! I was actually reading that issue, but this one sounded like this conversion was undesirable while the other issue almost sounded like a feature request. I didn't notice I'd jumped repos. Sorry about that, and I'll comment over there. Thanks!