当一个变量不是函数的一部分时,使用purrr :: map2

时间:2018-03-22 17:42:55

标签: r purrr

如果我有这样的功能:

foo <- function(var) {
  if(length(var) > 5) stop("can't be greater than 5")

  data.frame(var = var)
}

这有效:

df <- 1:20

foo(var = df[1:5])

但这不是:

foo(var = df)

所需的输出是:

   var
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
10  10
11  11
12  12
13  13
14  14
15  15
16  16
17  17
18  18
19  19
20  20

如果我知道我只能在5行的大块中运行这个函数,那么如果我想评估所有20行,那么最好的方法是什么?我可以使用purrr::map()吗?假设5行约束是刚性的。

提前致谢。

2 个答案:

答案 0 :(得分:1)

我们split df每个包含5个,然后使用purrr::map_dfrfoo函数应用于它们,然后bind按行划分所有内容

library(tidyverse)

foo <- function(var) {
  if(length(var) > 5) stop("can't be greater than 5")

  data.frame(var = var)
}

df <- 1:20
df_split <- split(df, (seq(length(df))-1) %/% 5)
df_split

map_dfr(df_split, ~ foo(.x))

   var
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
10  10
11  11
12  12
13  13
14  14
15  15
16  16
17  17
18  18
19  19
20  20

答案 1 :(得分:0)

您可以使用dplyr::group_bytapply

data.frame(df) %>%
  mutate(grp = (row_number()-1) %/% 5) %>%
  group_by(grp) %>%
  mutate(var = foo(df)$var) %>%
  ungroup %>%
  select(var)

# # A tibble: 20 x 1
#     var
# <int>
# 1     1
# 2     2
# 3     3
# 4     4
# 5     5
# 6     6
# 7     7
# 8     8
# 9     9
# 10    10
# 11    11
# 12    12
# 13    13
# 14    14
# 15    15
# 16    16
# 17    17
# 18    18
# 19    19
# 20    20

data.frame(var=unlist(tapply(df,(df-1) %/% 5,foo)))
#    var
# 01   1
# 02   2
# 03   3
# 04   4
# 05   5
# 11   6
# 12   7
# 13   8
# 14   9
# 15  10
# 21  11
# 22  12
# 23  13
# 24  14
# 25  15
# 31  16
# 32  17
# 33  18
# 34  19
# 35  20