能快速将复杂的list结构扁平化成dataframe

简单的讲,do.call 的功能就是执行一个函数,而这个函数的参数呢,放在一个list里面, 是list的每个子元素。它可以在实际调用函数时将参数以列表的形式传入,下面是一个简单的例子:

  1. > tmp <- data.frame('letter' = letters[1:10], 'number' = 1:10, 'value' = c('+','-'))
  2. > tmp
  3. letter number value
  4. 1 a 1 +
  5. 2 b 2 -
  6. 3 c 3 +
  7. 4 d 4 -
  8. 5 e 5 +
  9. 6 f 6 -
  10. 7 g 7 +
  11. 8 h 8 -
  12. 9 i 9 +
  13. 10 j 10 -
  14. > tmp[[1]]
  15. [1] a b c d e f g h i j
  16. > tmp[[2]]
  17. [1] 1 2 3 4 5 6 7 8 9 10
  18. > tmp[[3]]
  19. [1] + - + - + - + - + -
  20. > do.call("paste", c(tmp, sep = ""))
  21. [1] "a1+" "b2-" "c3+" "d4-" "e5+" "f6-" "g7+" "h8-" "i9+" "j10-"
  22. ## 调用函数时将参数以列表的形式传入

通过do.call(),实现多个数据框的合并。

tidyverse中

  1. > list1
  2. [[1]]
  3. up down number
  4. 1 A a 1
  5. 2 B b 2
  6. 3 C c 3
  7. 4 D d 4
  8. 5 E e 5
  9. [[2]]
  10. up down number
  11. 1 A a 1
  12. 2 B b 2
  13. 3 C c 3
  14. 4 D d 4
  15. 5 E e 5
  16. [[3]]
  17. up down number
  18. 1 A a 1
  19. 2 B b 2
  20. 3 C c 3
  21. 4 D d 4
  22. 5 E e 5
  23. > do.call("rbind",list1)
  24. up down number
  25. 1 A a 1
  26. 2 B b 2
  27. 3 C c 3
  28. 4 D d 4
  29. 5 E e 5
  30. 6 A a 1
  31. 7 B b 2
  32. 8 C c 3
  33. 9 D d 4
  34. 10 E e 5
  35. 11 A a 1
  36. 12 B b 2
  37. 13 C c 3
  38. 14 D d 4
  39. 15 E e 5

通过 do.call() 实现了内部函数对外部输入的自动匹配。

  1. #构建求和参数
  2. Sum <- function(a = 1, b = 2, c = 3, d = 4) {
  3. message("a:", a, " b:", b, " c:", c, " d:", d)
  4. return(sum(a, b, c, d))
  5. }
  6. Args <- expand.grid(
  7. c(1, 2),
  8. c(3, 4, 5),
  9. c(6, 7, 8, 9)
  10. )
  11. colnames(Args) <- c("a", "b", "c")
  12. batchSum <- function(ArgsMat) {
  13. args <- list()
  14. for (i in 1:nrow(ArgsMat)) {
  15. args_update <- c(args, ArgsMat[i, , drop = FALSE])
  16. do.call(Sum, args = args_update)
  17. }
  18. }
  19. batchSum(Args)
  20. #> a:1 b:3 c:6 d:4
  21. #> a:2 b:3 c:6 d:4
  22. #> a:1 b:4 c:6 d:4
  23. #> a:2 b:4 c:6 d:4
  24. #> a:1 b:5 c:6 d:4
  25. #> a:2 b:5 c:6 d:4
  26. #> a:1 b:3 c:7 d:4
  27. #> a:2 b:3 c:7 d:4
  28. #> a:1 b:4 c:7 d:4
  29. #> a:2 b:4 c:7 d:4
  30. #> a:1 b:5 c:7 d:4
  31. #> a:2 b:5 c:7 d:4
  32. #> a:1 b:3 c:8 d:4
  33. #> a:2 b:3 c:8 d:4
  34. #> a:1 b:4 c:8 d:4
  35. #> a:2 b:4 c:8 d:4
  36. #> a:1 b:5 c:8 d:4
  37. #> a:2 b:5 c:8 d:4
  38. #> a:1 b:3 c:9 d:4
  39. #> a:2 b:3 c:9 d:4
  40. #> a:1 b:4 c:9 d:4
  41. #> a:2 b:4 c:9 d:4
  42. #> a:1 b:5 c:9 d:4
  43. #> a:2 b:5 c:9 d:4
  44. colnames(Args) <- c("a", "c", "d")
  45. batchSum(Args)
  46. #> a:1 b:2 c:3 d:6
  47. #> a:2 b:2 c:3 d:6
  48. #> a:1 b:2 c:4 d:6
  49. #> a:2 b:2 c:4 d:6
  50. #> a:1 b:2 c:5 d:6
  51. #> a:2 b:2 c:5 d:6
  52. #> a:1 b:2 c:3 d:7
  53. #> a:2 b:2 c:3 d:7
  54. #> a:1 b:2 c:4 d:7
  55. #> a:2 b:2 c:4 d:7
  56. #> a:1 b:2 c:5 d:7
  57. #> a:2 b:2 c:5 d:7
  58. #> a:1 b:2 c:3 d:8
  59. #> a:2 b:2 c:3 d:8
  60. #> a:1 b:2 c:4 d:8
  61. #> a:2 b:2 c:4 d:8
  62. #> a:1 b:2 c:5 d:8
  63. #> a:2 b:2 c:5 d:8
  64. #> a:1 b:2 c:3 d:9
  65. #> a:2 b:2 c:3 d:9
  66. #> a:1 b:2 c:4 d:9
  67. #> a:2 b:2 c:4 d:9
  68. #> a:1 b:2 c:5 d:9
  69. #> a:2 b:2 c:5 d:9
  70. ##此时B是不会变的