2016-07-20 28 views
3

我正在寻求嵌套乐器的高效替代方案,我认为在R社区中不使用嵌套结构。任何人都可以提出可能的想法或方法来避免在自定义函数中使用嵌套lapply?如何避免在R中使用嵌套lapply?

这里是快速重复的例子:

模拟数据,我用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)) 

功能:

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) 
    }) 
}) 

目标:

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

如何避免在test中使用嵌套乐器?任何人都可以提出可能的想法来解决这个问题吗?由于

最好的问候:

杰夫

+0

您是否尝试在新的R会话中运行您的示例代码?你也应该描述你正在尝试做什么,而不是粘贴代码。 – hrbrmstr

+0

@hrbrmstr:是的,我试过了,但如果我在自定义函数中使用嵌套lapply,它会返回一些我不期望的东西。上面的代码是基于我的函数结果模拟的。我正在寻求替代处理大数据框架对象的嵌套结构的一般策略。避免这个问题的一般方法是什么? – user88911

+0

@Jimbou:我可以接受除列表类对象之外的所有可能的输出。你能否在这里详细说明你的可能方法? – user88911

回答

5

我不知道你真正想要的。但是,如果你喜欢这两个名单的所有组合的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 
+0

如果我们正在使用您的方法,是否可以获得与我所做的完全相同的输出格式?我认为使用expand.grid是非常聪明的事情,可能会产生我的预期输出。但是,如何将输出放入矩阵或data.frame?我想让相同尺寸的矢量放在一起。非常感谢你。 – user88911

+1

@ user88911使用一个有序的'a'像这样'a < - a [order(a $ Var1),]'? – Jimbou

+0

只是完美的答案。再次感谢您在这里的大力帮助。 – user88911

2

这是你想要的吗?

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 
+0

为什么使用mapply没有像我所做的那样返回正确的输出维度?如何通过使用mapply来实现这一点?谢谢 – user88911

+0

查看添加编辑 – Robert

+0

非常感谢。 – user88911