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

rowwise is broken for 'list' objects #1643

Closed
antoine-lizee opened this issue Jan 29, 2016 · 2 comments
Closed

rowwise is broken for 'list' objects #1643

antoine-lizee opened this issue Jan 29, 2016 · 2 comments
Assignees
Labels

Comments

@antoine-lizee
Copy link

@antoine-lizee antoine-lizee commented Jan 29, 2016

Might be related to #1491 and hybrid evaluation, but this a different issue.

This is a little involved (it took me quite a while to figure out the REPEX), so hang on:
When we assign a list object in a mutate call after a rowwise it seems that the values which depends on other columns are reassigned after all calls have been done to the last value of the column variable. It's one of the extremely weird bugs that only our dear R can produce.
The best real-world example would be fitting models with different parameters, but I cooked you a small repex:

ft <- function(test) {
  res <- list(tt = test, tt2 = !!test)
  test2 <- test
  res$tt3 <- test2
  return(res)
}

data.frame(prob = c(F,F,F,T)) %>% tbl_df %>% rowwise() %>% 
  mutate(model = list(ft(prob)),
         probFromModel = model[["tt"]],
         probAssignedFromModel = model[["tt3"]],
         probComputedFromModel = model[["tt2"]])
# Source: local data frame [4 x 5]
# Groups: <by row>
#   
#   prob     model probFromModel probAssignedFromModel probComputedFromModel
# (lgl)     (chr)         (lgl)                 (lgl)                 (lgl)
#1 FALSE <list[3]>          TRUE                  TRUE                 FALSE
#2 FALSE <list[3]>          TRUE                  TRUE                 FALSE
#3 FALSE <list[3]>          TRUE                  TRUE                 FALSE
#4  TRUE <list[3]>          TRUE                  TRUE                  TRUE

We can see that (i) the "test" value is right when it is evaluated, (ii) computed values (copied) are okay (iii) any value that are "shallowed" copied (even the re-assignment) are prone to the bug.

The function is here to test re-assignment, but doing something like model = list(list(tt=...)) works the same.

Seems like a bug around hybrid evaluation and the fact that we might want to enforce some kind of deep-copy of the arguments.

@antoine-lizee
Copy link
Author

@antoine-lizee antoine-lizee commented Jan 29, 2016

Seems like substitute() offers the right solution by evaluating the object at call time:


data.frame(prob = c(F,F,F,T)) %>% tbl_df %>% rowwise() %>% 
  mutate(model = list(ft(substitute(prob))),
         probFromModel = model[["tt"]],
         probAssignedFromModel = model[["tt3"]],
         probComputedFromModel = model[["tt2"]])
# Source: local data frame [4 x 5]
# Groups: <by row>
#   
#   prob     model probFromModel probAssignedFromModel probComputedFromModel
# (lgl)     (chr)         (lgl)                 (lgl)                 (lgl)
# 1 FALSE <list[3]>         FALSE                 FALSE                 FALSE
# 2 FALSE <list[3]>         FALSE                 FALSE                 FALSE
# 3 FALSE <list[3]>         FALSE                 FALSE                 FALSE
# 4  TRUE <list[3]>          TRUE                  TRUE                  TRUE

Loading

@antoine-lizee
Copy link
Author

@antoine-lizee antoine-lizee commented Feb 2, 2016

Thanks :-)

Loading

@lock lock bot locked as resolved and limited conversation to collaborators Jun 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants