R 中的 For 循环,用于自动计算 DataFrame 的平均值

For loop in R to automate mean calculations of Dataframes

提问人:Divad99 提问时间:11/13/2023 更新时间:11/13/2023 访问量:48

问:

以下用于计算数据帧的列平均值的代码有效:

res <- list()
for(i in 1:nrow(df))
  z <- df[i,]
  z <- unlist(z) 
  z <- mean(z)
  res[[i]] <- z
  print(res)

但是,如果我尝试将代码转换为函数,则输出列表会为每一列显示“NULL”,但最后一列除外:

res <- list()
col.mean <- function(x){
  for(i in 1:nrow(x))
    z <- x[i,]
    z <- unlist(z) 
    z <- mean(z)
    res[[i]] <- z
    return(res)
}

以下函数似乎正在工作,但我不明白它背后的逻辑。对我来说,这两个功能是相似的,只是后者更简单。

res <- list()
col.mean <- function(x){
  for(i in 1:nrow(x))
    res[[i]] <- mean(unlist(x[i,]))
    return(res)
}
R 函数 for 循环

评论

2赞 Friede 11/13/2023
你是说行的手段,然后改用。对于列,请使用 .rowMeans()colMeans()

答:

0赞 jkatam 11/13/2023 #1

我相信这对我有用,几乎没有变化,如下所示

res <- list()

col.mean <- function(x){
for(i in 1:nrow(x)){
  z <- x[i,]
z <- unlist(z) 
z <- mean(z)
res[[i]] <- z
return(res)
}
}

col.mean(iris)

print(res)
1赞 Friede 11/13/2023 #2

我假设您要计算行的平均值。

1. 一个快速函数存在于 : 中。有关详细信息,请参阅。base RrowMeans()help(rowMeans)

2. For-loops不是一种很像的做事方式。 对循环进行一些修改:R

# do not grow objects inside loops! 
res <- vector("list", nrow(data))
# I prefer seq(nrow(data) over 1:nrow(data)
for(i in seq(nrow(data))) {
  res[[i]] <- mean(unlist(data[i, ]))
}

包装到一个自写的函数中:

rowMeans2 <- \(df, ...) {
  res <- vector("list", nrow(df))
  for(i in seq(nrow(df))) {
    res[[i]] <- mean(unlist(df[i, ]), ...)
  }
  res
}

“-parameter/argument” 允许您指定参数,例如 ....mean()na.rm = TRUE

3. 在 中,我们经常使用 -functions(循环的包装器)而不是自写的循环。在这里,我使用了,因为您似乎希望将结果以列表格式存储。R*apply()lapply()

rowMeans3 <- \(df, ...) {
  lapply(X = seq(nrow(df)), FUN = \(i) mean(unlist(df[i, ]), ...))
}

4. 乌尔比纳@Jilber在下面的评论中建议的另一种避免:unlist()

rowMeans4 <- \(df, ...) {
  sapply(X = seq(nrow(df)), FUN = \(i) mean(as.numeric(df[i, ]), ...))
}

在名为“iris”的内置数据集上进行了测试。我删除了非数字列。数据:

data <- iris[, sapply(iris, is.numeric)]

评论

0赞 Jilber Urbina 11/13/2023
您可以使用代替和避免使用sapplylapplyunlist
0赞 Friede 11/13/2023
谢谢。我知道。 是提问者使用的。unlist(mean(...))
0赞 jkatam 11/13/2023
我认为这些方法存在挑战,因为它们都没有删除字符列。让我们以第一行的 DataFrame 为例,如果我们举例,结果是 2.24,但是如果我们实际上只考虑数值列,结果应该是 2.55。正确的代码是您提到的“iris[, sapply(iris, is.numeric)]”,但其他代码似乎不正确irissapply(1, \(x){ mean(unlist(iris[x,])) })
0赞 Friede 11/13/2023
在给定的示例中,将不同类型的数据组合在一起,数值和因子对我来说似乎毫无意义且危险。请注意,对于第一行,您的方法将“setosa”(因子水平)强制为“1”。行均值受到影响。