R- expand.grid给出了参数名称和序列定义的data.frame

时间:2018-03-22 15:26:12

标签: r dataframe seq

我有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找到一种方法来提出结果,而不是先单独构建序列。你有什么优雅的方法吗?

奖励荣誉,不仅包括数字序列,还包括矢量/字符集/其他因素。

非常感谢!

2 个答案:

答案 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的答案在技术上是正确的(并且可以说是因为它激发了这一点而被接受),但它也是在applydata.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)