如何在 purrr 循环中更新数据帧?

how to update a dataframe in a purrr loop?

考虑这个简单的例子

library(dplyr)
library(purrr)

mydata <- dplyr::data_frame('value' = c(1,2,3))
> mydata
# A tibble: 3 x 1
  value
  <dbl>
1    1.
2    2.
3    3.

我有一个将 dataframenumber 作为参数的函数,我想在每次迭代时就地修改数据框。

我写了以下内容,但它没有更新数据框:

  myfunc <- function(df, numba){
  name_var <- paste('year_', quo_name(numba), sep ='')
  df <- df %>% mutate(!!name_var := 1)
  return(df)
}

seq(2006, 2007, by = 1) %>% 
    purrr::walk(function(x) {mydata <- myfunc(mydata, x)})

很遗憾mydata修改不正确:

seq(2006, 2007, by = 1) %>% 
    map(function(x) {mydata <- myfunc(mydata, x)})

给出:

[[1]]
# A tibble: 3 x 2
  value year_2006
  <dbl>     <dbl>
1    1.        1.
2    2.        1.
3    3.        1.

[[2]]
# A tibble: 3 x 2
  value year_2007
  <dbl>     <dbl>
1    1.        1.
2    2.        1.
3    3.        1.

而预期的输出应该是

# A tibble: 3 x 3
  value year_2006 year_2007
  <dbl>     <dbl>     <dbl>
1    1.        1.        1.
2    2.        1.        1.
3    3.        1.        1.

我在这里错过了什么?谢谢!

首先,应该mydata <- data.frame('value' = c(1,2,3)),而不是mydata <- data_frame('value' = c(1,2,3))。现在,要解决您的问题,您应该 return 修改数据框。像这样:

myfunc <- function(df, numba){
    name_var <- paste('year_', quo_name(numba), sep ='')
    df <- df %>% mutate(name_var = 1)
    return(df)
}

编辑

尝试使用

seq(2006, 2007, by = 1) %>% 
 map(function(x) {mydata <- myfunc(mydata, x)})

map returns 结果列表。您可以使用 map_dfc 按列绑定每年的结果,然后删除额外的 value

    seq(2006, 2007, by = 1) %>% 
      map_dfc(function(x) {mydata <- myfunc(mydata, x)}) %>% 
      select(value, matches("year_"))

    # or even shorter
    seq(2006, 2007, by = 1) %>% 
      map_dfc(~ myfunc(mydata, .)) %>% 
      select(value, matches("year_"))

    # A tibble: 3 x 3
      value year_2006 year_2007
      <dbl>     <dbl>     <dbl>
    1    1.        1.        1.
    2    2.        1.        1.
    3    3.        1.        1.