如何避免在R中使用嵌套lapply?

时间:2016-07-20 10:06:17

标签: r performance function lapply

我正在寻找嵌套lapply的有效替代方案,我认为使用嵌套结构在R社区中不受欢迎。任何人都可以提出可能的想法,或者避免在自定义函数中使用nest lapply吗?

这是一个快速重现的例子:

模拟数据

private String getGroovyPath(MyTitleAreaDialog dialog)
{
String LayerLVS =     "lvs/dev/scripts/123/aderf/de/lock/clt/Simplescript.groovy";
String LayerPRJ = "prj/dev/scripts/123/aderf/de/lock/clt/Simplescript.groovy"";

if(dialog.getLayer().equalsIgnoreCase("LVS"))
{
    return LayerLVS;
}
else if(dialog.getLayer().equalsIgnoreCase("PRJ"))
{
    return LayerPRJ;
}
return null;
}

我使用嵌套lapply的函数,但想避免这种情况:

a <- data.frame(
  start=seq(1, by=9, len=18), stop=seq(6, by=9, len=18),
  ID=letters[seq(1:18)], score=sample(1:25, 18, replace = FALSE))
b <- data.frame(
  start=seq(2, by=11, len=20), stop=seq(8, by=11, len=20),
  ID=letters[seq(1:20)], score=sample(1:25, 20, replace = FALSE))
c <- data.frame(
  start=seq(4, by=11, len=25), stop=seq(9, by=11, len=25),
  ID=letters[seq(1:25)], score=sample(1:25, 25, replace = FALSE))

目的:

避免使用嵌套lapply,以找到其有效的替代方案。我的意思是找到更好的输出表示,它必须易于/快速重现,并允许快速/简单的下游计算。有没有一般的方法来做到这一点?

如何避免在a.big <- a[a$score >10,] a.sml <- a[(a$score > 6 & a$score <= 10),] a.non <- a[a$score < 6,] a_new <- list('big'=a.big, 'sml'=a.sml) tar.list <- list(b,c) test <- lapply(a_new, function(ele_) { re <- lapply(tar.list, function(li) { out <- base::setdiff(ele_, li) return(out) }) }) 中使用嵌套lapply?任何人都可以提出可能的想法来解决这个问题吗?谢谢

最好的问候:

杰夫

2 个答案:

答案 0 :(得分:3)

我不确定你真正想要的是什么。但是如果您喜欢两个列表的所有组合setdiff,那么您可以使用以下内容:

# all combinations
a <- expand.grid(seq_along(a_new), seq_along(tar.list))
a
  Var1 Var2
1    1    1
2    2    1
3    1    2
4    2    2
# apply over all combinations setdiff row-vice 
apply(a, 1, function(x, y, z){ setdiff(y[x[1]], z[x[2]])}, a_new, tar.list)[1:2]
[[1]]
[[1]][[1]]
   start stop ID score
2     10   15  b    21
3     19   24  c    12
6     46   51  f    23
9     73   78  i    15
10    82   87  j    19
11    91   96  k    25
13   109  114  m    11
16   136  141  p    17
17   145  150  q    18
18   154  159  r    24


[[2]]
[[2]][[1]]
   start stop ID score
5     37   42  e     9
14   118  123  n     8
15   127  132  o     7

使用双[[]]个brakets可以为您提供仅一个列表的清洁输出。

apply(a, 1, function(x, y, z){ setdiff(y[[x[1]]],z[[x[2]]])}, a_new, tar.list)

[[1]]
   start stop ID score
2     10   15  b    21
3     19   24  c    12
6     46   51  f    23
9     73   78  i    15
10    82   87  j    19
11    91   96  k    25
13   109  114  m    11
16   136  141  p    17
17   145  150  q    18
18   154  159  r    24

[[2]]
   start stop ID score
5     37   42  e     9
14   118  123  n     8
15   127  132  o     7

[[3]]
   start stop ID score
2     10   15  b    21
3     19   24  c    12
6     46   51  f    23
9     73   78  i    15
10    82   87  j    19
11    91   96  k    25
13   109  114  m    11
16   136  141  p    17
17   145  150  q    18
18   154  159  r    24

[[4]]
   start stop ID score
5     37   42  e     9
14   118  123  n     8
15   127  132  o     7

答案 1 :(得分:1)

这就是你想要的吗?

outd <- function(ele_, li) base::setdiff(ele_, li)
mapply(outd, a_new, tar.list, SIMPLIFY = FALSE)

> mapply(outd, a_new, tar.list, SIMPLIFY = FALSE)
$big
   start stop ID score
1      1    6  a    12
6     46   51  f    20
8     64   69  h    24
9     73   78  i    13
10    82   87  j    11
12   100  105  l    19
14   118  123  n    16
15   127  132  o    18
16   136  141  p    22
17   145  150  q    23
18   154  159  r    14

$sml
  start stop ID score
2    10   15  b     9
7    55   60  g    10

修改

在前一种情况下,mapply将函数应用于列表元素对。

如果我们从outer采用ideia扩展两个列表,我们得到(不确定是否会在其他情况下工作):

bY <- rep(tar.list, rep.int(length(a_new), length(tar.list)))
bX <- rep(a_new, times = ceiling(length(bY)/length(a_new)))
mapply(outd, bX, bY, SIMPLIFY = FALSE)

> mapply(outd, bX, bY, SIMPLIFY = FALSE)
$big
   start stop ID score
1      1    6  a    25
2     10   15  b    23
4     28   33  d    14
7     55   60  g    19
9     73   78  i    20
10    82   87  j    21
12   100  105  l    13
13   109  114  m    12
14   118  123  n    22
16   136  141  p    15
17   145  150  q    18

$sml
   start stop ID score
6     46   51  f     9
8     64   69  h     8
18   154  159  r    10

$big
   start stop ID score
1      1    6  a    25
2     10   15  b    23
4     28   33  d    14
7     55   60  g    19
9     73   78  i    20
10    82   87  j    21
12   100  105  l    13
13   109  114  m    12
14   118  123  n    22
16   136  141  p    15
17   145  150  q    18

$sml
   start stop ID score
6     46   51  f     9
8     64   69  h     8
18   154  159  r    10