R:如何简化重新运行的输出(来自purrr)?

时间:2018-08-21 17:00:20

标签: r purrr

(这是我对Stackflow的第一个问题:我希望自己摆正姿势)

我正在使用rerun(来自tidyverse purrr)重复一些计算。这是一个非常简化的示例(看似荒谬,但却说明了这一点)

library(tidyverse)

# Function to do the calculation 
do_rerun <- function(data_in){
  data_out <- data_in %>%   
    group_by(id) %>%
    transmute(result = do_calculation(x1, x2)) %>% 
    ungroup()
  return(data_out)
}

# Some test data
(test_data <- tibble(id = c("1","2","3","1","2","3","1","2","3"), 
                    day = c(1,1,1,2,2,2,3,3,3), 
                    x1 = runif(9), 
                    x2 = runif(9)) %>% 
  arrange(id,day))

# A tibble: 9 x 4
  id      day     x1     x2
  <chr> <dbl>  <dbl>  <dbl>
1 1         1 0.195  0.0854
2 1         2 0.884  0.0863
3 1         3 0.539  0.240 
4 2         1 0.696  0.262 
5 2         2 0.752  0.663 
6 2         3 0.477  0.252 
7 3         1 0.0387 0.494 
8 3         2 0.286  0.589 
9 3         3 0.0249 0.870 

# Do the calculation .n = 3 times
# The output of reun is a list,
# which in this case is a list of 3 unnamed tibbles
# each of which has an id and result column
(test <- rerun(.n = 3, do_rerun(test_data)))

# Output

[[1]]
# A tibble: 9 x 2
  id    result
  <chr>  <dbl>
1 1     0.0167
2 1     0.0763
3 1     0.129 
4 2     0.182 
5 2     0.499 
6 2     0.121 
7 3     0.0191
8 3     0.168 
9 3     0.0217

[[2]]
# A tibble: 9 x 2
  id    result
  <chr>  <dbl>
1 1     0.0167
2 1     0.0763
3 1     0.129 
4 2     0.182 
5 2     0.499 
6 2     0.121 
7 3     0.0191
8 3     0.168 
9 3     0.0217

[[3]]
# A tibble: 9 x 2
  id    result
  <chr>  <dbl>
1 1     0.0167
2 1     0.0763
3 1     0.129 
4 2     0.182 
5 2     0.499 
6 2     0.121 
7 3     0.0191
8 3     0.168 
9 3     0.0217

我想将这个三个小标题列表转换为一个包含id(来自第一个小标题)的id,然后是result1,result2,result3(即来自三个小标题的结果字段)。我可以使用

访问各个列
id_tibble <- as_tibble(test[[1]][["id"]])

result_tibble <- as_tibble(test[[1]][["result"]])

我想做的(至少对于结果列而言)是这样的:

new_tibble <- as_tibble(test[[1:3]][["result"]])

但是它会引发错误(“ test [[1:3]] [[“ result”]]:下标超出范围”)。

我想要获得的最终结构是:

id    result1 result2 result3
<chr> <dbl>   <dbl>   <dbl>
1     0.0167  0.0167  0.0167
1     0.0763  0.0763  0.0763
1     0.129   0.129   0.129 
2     0.182   etc.

也许这样做的方法是使用purrr(或其变体之一)中的map命令,但是我不知道该怎么做!

1 个答案:

答案 0 :(得分:2)

这是一个快速的解决方案:创建一个大型数据框并删除重复的id列:

test %>%
    purrr::map_dfc(cbind) %>%
    dplyr::select(-matches("id.+"))

(编辑:在下面添加了替代选项以保留在dplyr内;即,这将导致tibble

test %>%
    dplyr::bind_cols() %>%
    dplyr::select(-matches("id.+"))

我假设您知道在您的示例中所有三个结果都相同  并且在实际问题中结果是不同的。我也假设  您想将分析重新运行3次以上。 (如果我弄错了,请告诉我)