Цикл так, что он извлекает данные, а затем вычисляет среднее - PullRequest
0 голосов
/ 27 февраля 2019

Я пытался вычислить среднее значение для "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" для data(iris) с коэффициентом "Species".

Я знаю, что мы можем легко сделать это с aggregate() или apply() семействами, но яя пытаюсь сделать это, написав функцию, которая могла бы делать то же самое.

Я пытался сделать следующее: (1) создать подмножество, разделенное на «виды» (2) вычислить среднеедля каждого столбца для подмножества (3) Объединить в одну таблицу

new_iris <- function(df) {

  # Enter code here
  species = levels(df$Species)

  for (i in 1:length(species)) {
  subdata = subset(df, Species == species[i])
  means = colMeans(subdata[1:4])
}
 data.frame(species,means)
  }

Первой проблемой, с которой я столкнулся, была часть поднабора, которую я надеюсь зациклить, чтобы она возвращала три набора подданных.Но вместо этого он возвращает только один тип, например "virginica", когда я надеялся увидеть отдельные подмножества других типов.

Эта проблема снова связана с формированием фрейма данных.Поскольку длина не равна, это не позволяет мне создавать новый фрейм данных рассчитанных средних по видам.

1 Ответ

0 голосов
/ 27 февраля 2019

Я предполагаю, что то, что вы делаете, является некой формой учебного упражнения;поэтому я не буду комментировать другие / лучшие методы здесь.

Есть несколько проблем с вашим кодом, поэтому вот улучшенная версия

new_iris <- function(df) {

  # Enter code here
  species = levels(df$Species)

  data.frame(
      species,
      do.call(rbind, lapply(species, function(x)
          colMeans(df[df$Species == x, ][1:4]))))
}


new_iris(iris)
#species Sepal.Length Sepal.Width Petal.Length Petal.Width
#1     setosa        5.006       3.428        1.462       0.246
#2 versicolor        5.936       2.770        4.260       1.326
#3  virginica        6.588       2.974        5.552       2.026

Некоторые комментарии:

  1. Лучше / быстрее использовать прямую индексацию строк, чем subset.
  2. Нет необходимости в цикле for внутри вашей функции;вы можете использовать lapply для генерации list результатов для каждого элемента species;затем используйте do.call(rbind, ...), чтобы связать результаты вместе.
  3. Обычно целью написания функции является упрощение предоставления одной и той же функциональности различным данным.В случае вашей функции это сложно, так как вы косвенно предполагаете, что следующие данные о ваших данных df

    • df должны содержать столбец Species
    • df$Speciesдолжно быть factor

    В вашей функции нет проверок безопасности, поэтому, если вы передадите данные, которые не имеют «правильного» формата, функция выдаст довольно незаметную ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...