{"action":"created","issue":{"url":"https://api.github.com/repos/hadley/tidyr/issues/68","labels_url":"https://api.github.com/repos/hadley/tidyr/issues/68/labels{/name}","comments_url":"https://api.github.com/repos/hadley/tidyr/issues/68/comments","events_url":"https://api.github.com/repos/hadley/tidyr/issues/68/events","html_url":"https://github.com/hadley/tidyr/issues/68","id":62684529,"number":68,"title":"`spread` with missing keys returns error","user":{"login":"gregmacfarlane","id":2234830,"avatar_url":"https://avatars.githubusercontent.com/u/2234830?v=3","gravatar_id":"","url":"https://api.github.com/users/gregmacfarlane","html_url":"https://github.com/gregmacfarlane","followers_url":"https://api.github.com/users/gregmacfarlane/followers","following_url":"https://api.github.com/users/gregmacfarlane/following{/other_user}","gists_url":"https://api.github.com/users/gregmacfarlane/gists{/gist_id}","starred_url":"https://api.github.com/users/gregmacfarlane/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gregmacfarlane/subscriptions","organizations_url":"https://api.github.com/users/gregmacfarlane/orgs","repos_url":"https://api.github.com/users/gregmacfarlane/repos","events_url":"https://api.github.com/users/gregmacfarlane/events{/privacy}","received_events_url":"https://api.github.com/users/gregmacfarlane/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-03-18T12:42:36Z","updated_at":"2015-05-19T18:50:42Z","closed_at":null,"body":"Trying to create a cross tabulation using `tally()` combined with `spread()` works nicely, unless there are missing values in the key columns.\r\n\r\n    mtcars %>% \r\n      group_by(cyl, gear) %>%\r\n      tally() %>%\r\n      spread(gear, n, fill = 0)\r\n    Source: local data frame [3 x 4]\r\n    \r\n      cyl  3 4 5\r\n    1   4  1 8 2\r\n    2   6  2 4 1\r\n    3   8 12 0 2\r\n\r\n    mtcars %>%\r\n      mutate(\r\n        cyl = ifelse(cyl > 6, NA, cyl),\r\n        gear = ifelse(gear > 4, NA, gear)\r\n      ) %>%\r\n      group_by(cyl, gear) %>%\r\n      tally()\r\n    Source: local data frame [8 x 3]\r\n    Groups: cyl\r\n    \r\n      cyl gear  n\r\n    1   4    3  1\r\n    2   4    4  8\r\n    3   4   NA  2\r\n    4   6    3  2\r\n    5   6    4  4\r\n    6   6   NA  1\r\n    7  NA    3 12\r\n    8  NA   NA  2\r\n    \r\n    # DITTO # %>%\r\n      spread(gear, n)\r\n    Error in if (any(names2(x) == \"\")) { : \r\n      missing value where TRUE/FALSE needed\r\n\r\nIt seems like a good solution would be to either treat `NA` values as another key or to drop them from the resulting table, controlled by an option switch. Like `useNA = \"always\"` in the base `table()` function, but with better syntax. "},"comment":{"url":"https://api.github.com/repos/hadley/tidyr/issues/comments/103629556","html_url":"https://github.com/hadley/tidyr/issues/68#issuecomment-103629556","issue_url":"https://api.github.com/repos/hadley/tidyr/issues/68","id":103629556,"user":{"login":"jennybc","id":599454,"avatar_url":"https://avatars.githubusercontent.com/u/599454?v=3","gravatar_id":"","url":"https://api.github.com/users/jennybc","html_url":"https://github.com/jennybc","followers_url":"https://api.github.com/users/jennybc/followers","following_url":"https://api.github.com/users/jennybc/following{/other_user}","gists_url":"https://api.github.com/users/jennybc/gists{/gist_id}","starred_url":"https://api.github.com/users/jennybc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jennybc/subscriptions","organizations_url":"https://api.github.com/users/jennybc/orgs","repos_url":"https://api.github.com/users/jennybc/repos","events_url":"https://api.github.com/users/jennybc/events{/privacy}","received_events_url":"https://api.github.com/users/jennybc/received_events","type":"User","site_admin":false},"created_at":"2015-05-19T18:50:42Z","updated_at":"2015-05-19T18:50:42Z","body":"I just tripped on this same thing. Before I found this issue, I had made my own example, so will include here anyway. As for what to name the columns, it seems like an option to prepend the key name would be useful here and more generally.\r\n\r\n```\r\njtxt <- \"\r\nname, grp,    sex, age\r\n joe,   1,   male,  30\r\n jan,   1,     NA,  43\r\n jen,   1, female,  44\r\n pat,   2,     NA,  24\r\n pam,   2, female,  63\r\n peg,   2, female,  50\r\n\"\r\njdat <- read.csv(text = jtxt, stringsAsFactors = FALSE, strip.white = TRUE)\r\n```\r\n\r\nCross-tabulating and spreading with `(sex, grp)` works:\r\n\r\n```\r\n> jdat %>%\r\n+ count(sex, grp) %>%\r\n+ spread(grp, n, fill = 0)\r\nSource: local data frame [3 x 3]\r\n\r\n     sex 1 2\r\n1 female 1 2\r\n2   male 1 0\r\n3     NA 1 1\r\n```\r\n\r\nBut going the other way round, `(grp, sex)`, does not:\r\n\r\n```\r\n> jdat %>%\r\n+ count(grp, sex) %>%\r\n+ spread(sex, n, fill = 0)\r\nError in if (any(names2(x) == \"\")) { : \r\n  missing value where TRUE/FALSE needed\r\n```\r\n\r\nTo illustrate my proposal re column names, here's possible output:\r\n\r\n```\r\ngrp sex_female sex_male sex_NA\r\n  1          1        1      1\r\n  2          2        0      1\r\n```\r\n\r\nThe prepending would fix up the value of `NA` as a column name and would also help when the values are cryptic, e.g. naked integers like `cyl` and `gear` from `mtcars`."}}