Code
Suppose I have a tibble which contains both atomic vectors and objects:
library(dplyr)
set.seed(1)
(mdat <- data_frame(n = 2:5, mod = rep(list(lm(rnorm(10) ~ 1)), 4)))
# # A tibble: 4 × 2
#       n      mod
#   <int>   <list>
# 1     2 <S3: lm>
# 2     3 <S3: lm>
# 3     4 <S3: lm>
# 4     5 <S3: lm>
Now I want to use do to create a new data.frame:
ndat <- mdat %>% rowwise() %>% do(data.frame(mod2 = I(list(lm(rnorm(.$n) ~ 1)))))
Question
If I want to keep the original columns I see 2 possibilities:
- Add the columns explicitly in the - docall:- (mdat %>% rowwise() %>% do(data.frame(n = .$n, mod = I(list(.$mod)), mod2 = I(list(lm(rnorm(.$n) ~ 1)))))) # Source: local data frame [4 x 3] # Groups: <by row> # # A tibble: 4 × 3 # n mod mod2 # * <int> <list> <list> # 1 2 <S3: lm> <S3: lm> # 2 3 <S3: lm> <S3: lm> # 3 4 <S3: lm> <S3: lm> # 4 5 <S3: lm> <S3: lm>
- Add an artificial - idcolumn and join the data frames (output stripped):- left_join(mdat %>% mutate(id = 1:4), ndat %>% ungroup() %>% mutate(id = 1:4), by = "id")
Option 1 is error prone, because I have to hard-code all columns of mdat. Option 2 introduces a meaningless id column.
My question is: can I achieve the desired output directly via do? My first thought was to use
mdat %>% rowwise() %>% do(data.frame(., mod2 = I(list(lm(rnorm(.$n) ~ 1)))))
But this does not work because of column mod:
# Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : 
#   cannot coerce class ""lm"" to a data.frame
So do I have to rely on option 2, or is there a better way (better in the sense of avoiding additional columns and hard-coding columns)?
