我正在尝试解决以下问题:
考虑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不等。
如何创建这样的功能。我更喜欢矢量解决方案或使用应用族函数来优化速度。
答案 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)
}
dfr
和mat
的输出似乎就是您所描述的。
干杯!