Сопоставление имен наборов данных в R - PullRequest
1 голос
/ 09 мая 2020

Я пытаюсь проанализировать кадр данных iris с помощью кластерного анализа. Здесь мне был предоставлен способ использования Map в R для сопоставления данных с наборами комбинаций гиперпараметров, перечисленных 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: оператор $ недопустим для векторов atomi c». Я пробовал писать as.character(tests[[2]]) вместо этого с тем же сообщением об ошибке. Я даже пробовал такие варианты, как ds %>% .[,"Species"]) и ds %>% .[,1:4], и в этом случае я получаю другое сообщение об ошибке: «Ошибка в. [,« Виды »]: неправильное количество размеров».

Любая идея как это исправить?

Изменить:

Просто попытался использовать lapply в списке DS и после помещения остальной части вышеперечисленного в функцию, и это дало мне то же самое сообщение об ошибке.

1 Ответ

1 голос
/ 09 мая 2020

Проблема в том, что 'ds' - это строка, нам нужно получить значение с помощью mget или get

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]]))
...