创建序列组合

时间:2014-09-07 17:36:08

标签: r

我正在尝试解决以下问题:

考虑5个简单序列:0:100,100:0,代表(0,101),代表(50,101),代表(100,101)

我需要3组数字变量,在所有组合中都有上面的序列。由于有5个序列和3个变量,因此可以有5 * 5 * 5个组合,因此每个变量总共有12625(5 * 5 * 5 * 101)个数字(每个序列有101个)。

这些可以分组为12625行和4列的data.frame。第一列(V)将只有seq(1:12625)(可以在其位置使用rownumbers)。其他3列(A,B,C)将具有不同组合的5个以上序列。例如,前101行在所有3 A,B和C中将具有0:100。接下来101行在A和B中将具有0:100,在C中具有100:0等等...

我可以创建序列:

s = list()
s[[1]] = 0:100
s[[2]] = 100:0
s[[3]] = rep(0,101)
s[[4]] = rep(50,101)
s[[5]] = rep(100,101)

但是如何进一步前进?我真的不需要数据框但是我需要一个函数来返回一个列表,其中包含发送给它的数字(第一列或第V列)的c(A,B,C)值。这个数字显然可以从1到12625不等。

如何创建这样的功能。我更喜欢矢量解决方案或使用应用族函数来优化速度。

2 个答案:

答案 0 :(得分:4)

您要求提供矢量化解决方案,所以这里仅使用data.table(类似于@SimonGs方法)

library(data.table)
grd <- CJ(A = seq_len(5), B = seq_len(5), C = seq_len(5))
res <- grd[, lapply(.SD, function(x) unlist(s[x]))]
res
#          A   B   C
#     1:   0   0   0
#     2:   1   1   1
#     3:   2   2   2
#     4:   3   3   3
#     5:   4   4   4
#  ---            
# 12621: 100 100 100
# 12622: 100 100 100
# 12623: 100 100 100
# 12624: 100 100 100
# 12625: 100 100 100

答案 1 :(得分:2)

我想出了两个解决方案。我发现这很难与apply等相关,因为它们往往会提供一个不太好处理的输出(也许有人可以&#34;驯服&#34;它们比我更好:D)< / p>

第一个解决方案使用对lapply的单独调用,第二个使用for循环和一些编程No-No。我个人更喜欢第二个,但第一个更快... ...

grd <- expand.grid(a=1:5,b=1:5,c=1:5)

# apply-ish
A <- lapply(grd[,1], function(z){ s[[z]] })
B <- lapply(grd[,2], function(z){ s[[z]] })
C <- lapply(grd[,3], function(z){ s[[z]] })
dfr <- data.frame(A=do.call(c,A), B=do.call(c,B), C=do.call(c,C))

# for-ish
mat <- NULL
for(i in 1:nrow(grd)){
 cur <- grd[i,]
 tmp <- cbind(s[[cur[,1]]],s[[cur[,2]]],s[[cur[,3]]])
 mat <- rbind(mat,tmp)
}

dfrmat的输出似乎就是您所描述的。

干杯!