将列表粘贴到矢量,重复每个矢量级别的列表

时间:2017-09-29 02:47:29

标签: r list combinations apply paste

我想完成以下任务,而不必输入for循环,而是在单个apply()命令中。

我有一个列表a我希望重复N次,其中N是向量b的长度,粘贴a的每次重复到b的元素。

到目前为止,我已完成以下MWE:

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

如果我可以在b之前粘贴a,那将是最佳选择。

请注意我的起点是3个向量:vartreatspec,因此可以随意更改任何内容。

3 个答案:

答案 0 :(得分:4)

选项1:我们可以在没有任何apply()循环的情况下完成此操作。设unlist() a列表,paste()为已复制的b值,然后relist()基于已复制的a列表。试试这个:

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

检查:

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

b之前a的选项1:现在,要将b值放在前面,只需交换paste()中的参数即可拨打:

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

选项2:此选项确实使用apply()循环。在这里,我们使用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

b之前a的选项2:只需交换传递给Map()的未命名paste()参数。

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

答案 1 :(得分:1)

接近OP的方法,这可以通过嵌套development: secret_key_base: 231bf79489c63f8c8facd7... action_cable_url : http://localhost:<%= ENV["PORT"] %> test: secret_key_base: 1ab8adbcf8410aebb... action_cable_url : http://localhost:<%= ENV["PORT"] %> # Do not keep production secrets in the repository, # instead read values from the environment. production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> action_cable_url : <%= ENV["SERVER_PORT"] %> 使用匿名函数来解决:

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" 粘贴在b前面。压缩顶级列表需要a

验证方法是否有效(unlist()前面ab进行比较):

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

答案 2 :(得分:1)

这是一种完全不同的方法,它从头开始创建标签并以36行x 2列data.table返回它们,而不是包含36个长度为2的向量的列表:

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