2017-09-29 18 views
3

ループを入力せずに、ただ1つのapply()コマンドで次のタスクを実行したい。ベクトルにリストを貼り付け、ベクトルレベルごとにリストを繰り返す

私はNbの要素にaの各繰り返しを貼り付け、ベクトルbの長さであるN回、繰り返したいリストaを持っています。私はabを貼り付けることができればそれが最適だろう

var <- paste("var", 1:4, sep="") 
treat <- c("A","B") 
spec <- paste("sp", 1:3, sep="") 
a <- combn(var, 2, simplify = FALSE)#this 6 times, for each treatment and species 
b <- do.call(paste, c(expand.grid(treat, spec), sep='.')) 
a1 <- lapply(a, paste, b[1], sep='.') 
a2 <- lapply(a, paste, b[2], sep='.') 
a3 <- lapply(a, paste, b[3], sep='.') 
a4 <- lapply(a, paste, b[4], sep='.') 
a5 <- lapply(a, paste, b[5], sep='.') 
a6 <- lapply(a, paste, b[6], sep='.') 
a.final <- c(a1,a2,a3,a4,a5,a6) 
a.final 

これまでのところ私は、次のMWEを行っています。

私の出発点は、var,treatspecの3つのベクトルですので、その点から何かを自由に変更してください。

答えて

4

オプション1:apply()ループなしでこれを達成できます。 unlist()aリストpaste()を複製したbの値に、次にrelist()の値を複製したaのリストに基づいてください。

:ちょうど paste()呼び出しの引数を入れ替え、フロントから b値を置くために、今:

aa <- relist(
    paste(unlist(a), rep(b, each=sum(lengths(a))), sep="."), 
    rep.int(a, length(b)) 
) 

チェック:ab

identical(aa, a.final) 
# [1] TRUE 

オプション1本をお試しください

relist( paste(rep(b, each=sum(lengths(a))), unlist(a), sep = "."), rep.int(a, length(b)) ) 

オプション2:このオプションは、apply()ループを使用します。ここでは、1対1の貼り付けを行うにはMap()を使用します。

ra <- rep(a, length(b)) 
aa2 <- Map(paste, ra, relist(rep(b, each=sum(lengths(a))), ra), sep = ".") 

チェック:

identical(aa2, a.final) 
# [1] TRUE 

オプション2 ba前:だけpaste()に渡される無名のMap()引数を入れ替えます。 OPのアプローチに近い滞在

ra <- rep(a, length(b)) 
Map(paste, relist(rep(b, each=sum(lengths(a))), ra), ra, sep = ".") 
+0

!本当にありがとう – DaniCee

1

、これは無名関数を使用して、ネストしたlapply()で解決することができます。

unlist(lapply(b, function(x) lapply(a, function(y) paste(x, y, sep = "."))), 
     recursive = FALSE) 
[[1]] 
[1] "A.sp1.var1" "A.sp1.var2" 

[[2]] 
[1] "A.sp1.var1" "A.sp1.var3" 

[[3]] 
[1] "A.sp1.var1" "A.sp1.var4" 

... 

[[34]] 
[1] "B.sp3.var2" "B.sp3.var3" 

[[35]] 
[1] "B.sp3.var2" "B.sp3.var4" 

[[36]] 
[1] "B.sp3.var3" "B.sp3.var4" 

注意、baの前に貼り付けられます。トップレベルのリストを平坦化するにはunlist()が必要です。アプローチを検証するために

は(a.finalと比較するbの前にa)に取り組んでいる:

identical(a.final, 
      unlist(lapply(b, function(x) lapply(a, function(y) paste(y, x, sep = "."))), 
       recursive = FALSE)) 
[1] TRUE 
1

これはスクラッチからラベルを作成し、それらを返す完全に異なるアプローチであります36行×2列data.table、長さ2の36個のベクトルを含むリストの代わりに:

library(data.table) 
# cross join of treat, spec, var. Note, full labels will be created in sprintf() below 
DT <- CJ(LETTERS[1:2], 1:3, 1:4) 
# non equi join as replacement of combn() 
DT[DT, on = .(V1, V2, V3 > V3), nomatch = 0L, 
    # create labels 
    .(sprintf("%s.sp%s.var%i", V1, V2, V3), 
    sprintf("%s.sp%s.var%i", V1, V2, x.V3))] 
それだ
  V1   V2 
1: A.sp1.var1 A.sp1.var2 
2: A.sp1.var1 A.sp1.var3 
3: A.sp1.var1 A.sp1.var4 
4: A.sp1.var2 A.sp1.var3 
5: A.sp1.var2 A.sp1.var4 
6: A.sp1.var3 A.sp1.var4 
7: A.sp2.var1 A.sp2.var2 
... 
29: B.sp2.var2 B.sp2.var4 
30: B.sp2.var3 B.sp2.var4 
31: B.sp3.var1 B.sp3.var2 
32: B.sp3.var1 B.sp3.var3 
33: B.sp3.var1 B.sp3.var4 
34: B.sp3.var2 B.sp3.var3 
35: B.sp3.var2 B.sp3.var4 
36: B.sp3.var3 B.sp3.var4 
      V1   V2 
関連する問題