【问题标题】:Map over dataset names in R在 R 中映射数据集名称
【发布时间】:2020-05-09 14:14:13
【问题描述】:

我正在尝试使用聚类分析来分析 iris 数据框。这里向我提供了一种在 R 中使用 Map 将数据映射到 expand.grid 列出的超参数组合集并将所有结果收集到一个表中的方法。

我现在想同时对数据框的修改版本执行此操作。比如:

acc <- function(x){
  first = sum(x)
  second = sum(x^2)
  return(list(First=first,Second=second))
}
tests <- expand.grid(Clustering_Algorithm=c("ward.D","ward.D2","single","complete","average","mcquitty","median","centroid"),
                     DS=c("iris0","iris1","iris2"))
iris0 <- iris
iris1 <- cbind(log(iris[,1:4]),iris[5])
iris2 <- cbind(sqrt(iris[,1:4]),iris[5])
Table <- Map(function(x, ds){acc(table(ds$Species, cutree(hclust(dist(ds.[,1:4]),method=x),3)))},tests[[1]], tests[[2]])

这无法为我运行,并出现错误“ds$Species 中的错误:$ 运算符对原子向量无效”。我试过写as.character(tests[[2]]),但它有同样的错误信息。我什至尝试过ds %&gt;% .[,"Species"])ds %&gt;% .[,1:4] 之类的选项,在这种情况下,我会收到不同的错误消息:“Error in .[, "Species"] : wrong number of dimensions"。

知道怎么解决吗?

编辑:

刚刚尝试在列表DS 上使用lapply,然后将上面的其余部分放入一个函数中,这给了我完全相同的错误消息。

【问题讨论】:

  • 您正在调用ds.,而它是ds,它也是一个字符串(转换为字符)

标签: r combinations apply


【解决方案1】:

问题是'ds'是一个字符串,我们需要用mgetget获取值

Map(function(x, ds){
    acc(table(get(ds)$Species, cutree(hclust(dist(get(ds)[,1:4]),method=x),3)))
          }, as.character(tests[[1]]), as.character(tests[[2]]))

如果我们使用mget,它可以变得更紧凑

Map(function(x, ds) {
      acc(table(ds$Species, cutree(hclust(dist(ds[, 1:4]), method = x), 3)))
   }, as.character(tests[[1]]), mget(as.character(tests[[2]])))
#$ward.D
#$ward.D$First
#[1] 150

#$ward.D$Second
#[1] 6492


#$ward.D2
#$ward.D2$First
#[1] 150

#$ward.D2$Second
#[1] 6352
#....

如果我们想用具有列索引子集的字符串更改“测试”,而不是mget,请使用eval(parse

tests <- tests[1:4, ] # subset the first four rows
tests$DS <- c("iris0[,1:4]","iris1[,1:3]","iris2[,2:4]", "iris0[, 1:3]")

Map(function(x, ds) {
   ds1 <- eval(parse(text = ds))
   sp <- get(sub("\\s*\\[.*", "", ds))$Species
  acc(table(sp, cutree(hclust(dist(ds1), method = x), 3))) 
   }, as.character(tests[[1]]), as.character(tests[[2]]))

【讨论】:

  • 谢谢,当然这对我很有帮助(如你所见)——所以我赞成。但我仍然希望能够保留超参数中的行名和 acc 中的列名,而无需稍后重新插入。我认为它会使用 unlist() 然后应用于超参数行或类似的东西,因为我认为 unlist 至少与 expand.grid 结合使用很常见,并且 apply 是 for 循环的更好替代方案。
  • (对于其他人,这是参考我之前在stackoverflow.com/questions/61687341/…提出的问题)
  • @MobeusZoom 如果“DS”列包含“iris0[, 1:4]”等元素,您可以使用eval(parse(text = "iris0[, 1:4]"))
  • @MobeusZoom 已更新。如果每个数据集中的“物种”列不同,您可能希望将另一个向量作为Map 的参数,然后使用get(sub("\\s*\\[.*", "", ds))[[nm1]],其中function(x, ds, nm1)Map 的参数将是as.character(tests[[1]]), as.character(tests[[2]]), vecofspeciescolnames)
  • 谢谢!!而且您甚至想到了进一步的概括,我相信这也会有所帮助。现在,基本上,来自不同数据集的聚类结果可以以矢量化的方式存储。非常感谢你:)
猜你喜欢
  • 2018-03-11
  • 2021-11-25
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多