我正在尝试编写一个首先检查它是否是数据帧的for循环。如果它是数据框,则迭代数据帧并计算平均值,然后创建具有平均值的新列。这是一个例子:
df1 <- data.frame(
Number = c(45,62,27,34,37,55,40))
df2 <- data.frame(
Number = c(15,20,32,21,17,18,13))
df3 <- data.frame(
Number = c(12,32,22,14,16,21,30))
L <- list(df1,df2,df3)
for(i in L){if(is.data.frame(i)){
i$Average <- mean(i)
}
}
和df1之后的结果示例是:
Number Average
1 45 42.85714
2 62 42.85714
3 27 42.85714
4 34 42.85714
5 37 42.85714
6 55 42.85714
7 40 42.85714
谢谢!
答案 0 :(得分:2)
如果我们需要使用新值更新原始data.frame对象,请使用assign
nm1 <- paste0("df", 1:3)
for(i in seq_along(L)) {
assign(nm1[i], `[<-`(L[[i]], "Average", value = mean(L[[i]]$Number)))
}
df1
# Number Average
#1 45 42.85714
#2 62 42.85714
#3 27 42.85714
#4 34 42.85714
#5 37 42.85714
#6 55 42.85714
#7 40 42.85714
关于为什么OP的循环不起作用,
for(i in L) print(i)
返回list
的值,而不是对象的名称。所以,我们不能分配i$Average <-
。 list
元素没有名称。另外,mean
适用于vector
。它可以直接应用于data.frame
mean(L[[1]])
#[1] NA
警告消息:在mean.default(L [[1]])中:参数不是数字或 逻辑:返回NA
mean(L[[1]]$Number)
#[1] 42.85714
在for
循环中,这意味着我们获得了NAs
for(i in L) mean(i)
# Warning messages:
#1: In mean.default(i) : argument is not numeric or logical: returning NA
#2: In mean.default(i) : argument is not numeric or logical: returning NA
#3: In mean.default(i) : argument is not numeric or logical: returning NA
一旦我们提取专栏&#39;数字&#39;,mean
作品
for(i in L) print(mean(i$Number))
#[1] 42.85714
#[1] 19.42857
#[1] 21
但是,更容易将其保留在list
中并更新list
中的数据集。使用lapply
创建一列“平均值”&#39;循环遍历list
并获取&#39;数字&#39;
mean
lapply(L, transform, Average = mean(Number))
或tidyverse
library(tidyverse)
L %>%
map(~ .x %>%
mutate(Average = mean(Number)))
答案 1 :(得分:1)
您可以使用purrr::map
执行此操作:
require(purrr)
L %>%
map(
.f =
~ .x %>%
{
if (is.data.frame(.)) {
mutate(., Average = mean(Number))
}
}
)
# [[1]]
# Number Average
# 1 45 42.85714
# 2 62 42.85714
# 3 27 42.85714
# 4 34 42.85714
# 5 37 42.85714
# 6 55 42.85714
# 7 40 42.85714
#
# [[2]]
# Number Average
# 1 15 19.42857
# 2 20 19.42857
# 3 32 19.42857
# 4 21 19.42857
# 5 17 19.42857
# 6 18 19.42857
# 7 13 19.42857
# [[3]]
# Number Average
# 1 12 21
# 2 32 21
# 3 22 21
# 4 14 21
# 5 16 21
# 6 21 21
# 7 30 21
答案 2 :(得分:1)
i
只是用于控制for
循环的临时对象。要对存储在循环外L
中的数据帧进行更改,请尝试按照这样的数字进行索引。
df1 <- data.frame(Number = c(45,62,27,34,37,55,40))
df2 <- data.frame(Number = c(15,20,32,21,17,18,13))
df3 <- data.frame(Number = c(12,32,22,14,16,21,30))
L <- list(df1,df2,df3)
for(i in 1:length(L)){if(is.data.frame(L[[i]])){
## Requires explicitly extracting the values in
## L[[i]] by name. So could be problematic if you actually
## have many columns in your dataframes.
L[[i]]$Average <- mean(L[[i]]$Number)
}
}