循环以便提取数据,然后计算均值

时间:2019-02-27 00:45:06

标签: r

我一直在尝试通过因子"Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"计算data(iris)的{​​{1}}的平均值。

我知道我们可以很容易地使用"Species"aggregate()系列来做到这一点,但是我试图通过编写一个可能做同样事情的函数来做到这一点。

我一直想做的是: (1)创建一个按“种类”划分的子集 (2)计算子集每一列的平均值 (3)合并成一张桌子

apply()

我遇到的第一个问题是子集部分,我希望循环该子集部分,以便它返回三组子数据。但是,相反,当我希望看到其他类型的单独子集时,它只返回一种类型,例如“ virginica”。

此问题再次与形成数据帧有关。由于长度不相等,因此不允许我根据物种创建新的计算均值的数据框。

1 个答案:

答案 0 :(得分:0)

我认为您正在做的是某种形式的教育锻炼;因此在这里我不会评论其他/更好的方法。

您的代码存在一些问题,因此这是一个改进的版本

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循环;您可以使用lapplylist的每个元素生成species个结果;然后使用do.call(rbind, ...)将结果按行绑定在一起。
  3. 通常,编写函数的目的是为了更轻松地为不同的数据提供相同的功能。就您的功能而言,这很困难,因为您隐式地假设了有关数据df

    的以下情况
    • df必须包含一列Species
    • df$Species必须是factor

    函数中没有安全检查,因此,如果传递的数据格式不正确,则该函数将引发一个相当无法描述的错误。