我有data.frame
任意定义参数名称和序列边界:
dfParameterValues <- data.frame(ParameterName = character(), seqFrom = integer(), seqTo = integer(), seqBy = integer())
row1 <- data.frame(ParameterName = "parameterA", seqFrom = 1, seqTo = 2, seqBy = 1)
row2 <- data.frame(ParameterName = "parameterB", seqFrom = 5, seqTo = 7, seqBy = 1)
row3 <- data.frame(ParameterName = "parameterC", seqFrom = 10, seqTo = 11, seqBy = 1)
dfParameterValues <- rbind(dfParameterValues, row1)
dfParameterValues <- rbind(dfParameterValues, row2)
dfParameterValues <- rbind(dfParameterValues, row3)
我想使用这种方法根据ParameterName
,{seqFrom
给出的序列的所有可能组合的r行的唯一seqTo
的数量来创建c参数列的网格。 {1}}和seqBy
。因此,结果看起来有点像这样,或者应该有如下内容:
ParameterA ParameterB ParameterC
1 5 10
1 5 11
1 6 10
1 6 11
1 7 10
1 7 11
2 5 10
2 5 11
2 6 10
2 6 11
2 7 10
2 7 11
编辑:请注意,参数名称及其编号事先不知道。 data.frame来自其他地方所以我不能使用标准的静态expand.grid方法,需要像灵活的函数一样,根据任何带有ParameterName,seqFrom,seqTo,seqBy列的数据框创建扩展网格。
我一直在玩for循环(这开始很糟糕)并且它没有引导我任何优雅的想法。我似乎无法通过使用tidyr找到一种方法来提出结果,而不是先单独构建序列。你有什么优雅的方法吗?
奖励荣誉,不仅包括数字序列,还包括矢量/字符集/其他因素。
非常感谢!
答案 0 :(得分:0)
关闭CPak的答案,你可以使用
my_table <- expand.grid(apply(dfParameterValues, 1, function(x) seq(as.numeric(x['seqFrom']), as.numeric(x['seqTo']), as.numeric(x['seqBy']))))
names(my_table) <- c("ParameterA", "ParameterB", "ParameterC")
my_table <- my_table[order(my_table$ParameterA, my_table$ParameterB), ]
答案 1 :(得分:0)
@ smanski的答案在技术上是正确的(并且可以说是因为它激发了这一点而被接受),但它也是在apply
与data.frame
一起使用时要小心的一个很好的例子。秒。在这种情况下,框架包含至少一个character
的列,因此所有列都会被转换,因此需要使用as.numeric
。更安全的替代方案是仅拉出所需的列,例如:
expand.grid(apply(dfParameterValues[,-1], 1,
function(x) seq(x['seqFrom'], x['seqTo'], x['seqBy']) ))
expand.grid(apply(dfParameterValues[,c("seqFrom","seqTo","seqBy")], 1,
function(x) seq(x['seqFrom'], x['seqTo'], x['seqBy']) ))
我更喜欢第二种,因为它只能拉动它所需要的东西,因此它能够了解它所知道的#34;应该是数字。 (我发现显式通常更安全。)
发生这种情况的原因是apply
默默地将数据转换为matrix
,因此要查看效果,请尝试:
str(as.matrix(dfParameterValues))
# chr [1:3, 1:4] "parameterA" "parameterB" "parameterC" " 1" " 5" ...
# - attr(*, "dimnames")=List of 2
# ..$ : chr [1:3] "1" "2" "3"
# ..$ : chr [1:4] "ParameterName" "seqFrom" "seqTo" "seqBy"
str(as.matrix(dfParameterValues[c("seqFrom","seqTo","seqBy")]))
# num [1:3, 1:3] 1 5 10 2 7 11 1 1 1
# - attr(*, "dimnames")=List of 2
# ..$ : chr [1:3] "1" "2" "3"
# ..$ : chr [1:3] "seqFrom" "seqTo" "seqBy"
(注意第一个chr
和第二个num
。
两者都不保留参数名称。为此,请使用setNames
:
setNames(
expand.grid(apply(dfParameterValues[,c("seqFrom","seqTo","seqBy")], 1,
function(x) seq(x['seqFrom'], x['seqTo'], x['seqBy']) )),
dfParameterValues$ParameterName)