【问题标题】:R- expand.grid given a data.frame of parameter names and sequence definitionsR- expand.grid 给定参数名称和序列定义的data.frame
【发布时间】:2018-03-22 15:26:11
【问题描述】:

我有一个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)

我想使用这种方法创建一个基于唯一ParameterNames 的数量的 c 参数列网格,其中包含由seqFromseqToseqBy。因此,结果看起来有点像这样,或者应该有如下内容:

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 来得出结果的方法,而无需先单独构建序列。你有什么优雅的方法吗?

将其扩展到不仅包括数字序列,还包括向量/字符集/其他因素,这是一种奖励。

非常感谢!

【问题讨论】:

  • 试试paramA &lt;- 1:2; paramB &lt;- 5:7; paramC &lt;- 10:11; expand.grid(paramA, paramB, paramC)
  • 谢谢,CPak;也许我应该更清楚地指出,参数名称及其编号是事先不知道的。 data.frame 来自其他地方,所以我不能使用静态 expand.grid 方法。我会相应地编辑我的帖子。
  • 我正在寻找的解决方案可能看起来像这样(虽然这里是一种非常高级的愚蠢方法):lapply(originalDataFrame, expand.grid, lapply(???, seq))

标签: r dataframe seq


【解决方案1】:

离开 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), ]

【讨论】:

  • 不错!这看起来非常优雅,可以用来获得数字组合。有没有办法将参数名称作为列名包含在内?
  • 谢谢!这是我的方法,以便能够使用任意数量的(未知)参数名称:`grid
【解决方案2】:

@smanski 的回答在技术上是正确的(可以说应该被接受,因为它激发了这一点),但它也是一个很好的例子,说明在使用 applydata.frames 时要小心。在这种情况下,框架至少包含一列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']) ))

我更喜欢第二种,因为它只提取它需要的东西,因此它“知道”的应该是数字。 (我发现 explicit 通常更安全。)

发生这种情况的原因是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)

【讨论】:

  • 是的,我想知道如何转换为矩阵。感谢您提供非常灵活和优雅的解决方案!
猜你喜欢
  • 2018-11-08
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 2016-08-21
  • 2021-07-29
  • 1970-01-01
  • 2011-05-01
相关资源
最近更新 更多