在R中对多个数据框执行相同的函数

22

我刚开始学习R,有一个非常简单的问题。我找到了很多与我想要的类似的内容,但并不完全一样。基本上,我有多个数据框架,我只想在它们所有的数据框架上运行相同的函数。使用for-loop可以工作,但我不确定如何设置它来调用数据框架。看起来大多数人更喜欢使用R中的lapply方法。我也尝试了get函数,但没有成功。如果这是一个重复的问题,我很抱歉。任何帮助都将不胜感激!

这里是我过度简化的例子:2个数据框架:df1、df2。

df1
start stop ID
0     10   x
10    20   y
20    30   z

df2
start stop ID
0     10   a
10    20   b
20    30   c

我想要的是一个带有两个DataFrame开始和结束时间平均值的第四列。

df1
start stop ID  Avg
0     10   x    5 
10    20   y    15
20    30   z    25

我可以逐个数据框处理它们,使用:

df1$Avg <- rowMeans(subset(df1, select = c(start, stop)), na.rm = TRUE)

但我想在所有的数据框上运行它。


我觉得这条路是正确的,只是我无法像上面的rowMeans函数一样使用一个函数来使它工作。 - user3272284
4个回答

25

列出数据框的列表,然后使用lapply函数将该功能应用于它们所有。

df.list <- list(df1,df2,...)
res <- lapply(df.list, function(x) rowMeans(subset(x, select = c(start, stop)), na.rm = TRUE))
# to keep the original data.frame also
res <- lapply(df.list, function(x) cbind(x,"rowmean"=rowMeans(subset(x, select = c(start, stop)), na.rm = TRUE)))
将逐个顺序输入每个数据框作为X。

9
将它们放入列表中,然后在列表上运行rowMeans
df1 <- data.frame(x = rep(3, 5), y = seq(1, 5, 1), ID = letters[1:5])
df2 <- data.frame(x = rep(5, 5), y = seq(2, 6, 1), ID = letters[6:10])

lapply(list(df1, df2), function(w) { w$Avg <- rowMeans(w[1:2]); w })

 [[1]]
   x y ID Avg
 1 3 1  a 2.0
 2 3 2  b 2.5
 3 3 3  c 3.0
 4 3 4  d 3.5
 5 3 5  e 4.0

 [[2]]
   x y ID Avg
 1 5 2  f 3.5
 2 5 3  g 4.0
 3 5 4  h 4.5
 4 5 5  i 5.0
 5 5 6  j 5.5

3
一个类似于lapply()的函数(){})代码,如何使用lapply函数中使用的函数重新编写原始数据框? - Evan

6
如果您希望将所有输出保存在同一文件中,则可以使用以下方法。
 df1 <- data.frame(x = rep(3, 5), y = seq(1, 5, 1), ID = letters[1:5])
 df2 <- data.frame(x = rep(5, 5), y = seq(2, 6, 1), ID = letters[6:10])

 z=list(df1,df2)
 df=NULL
 for (i in z) {
 i$Avg=(i$x+i$y)/2
 df<-rbind(df,i)
 print (df)
 }

 > df
   x y ID Avg
1  3 1  a 2.0
2  3 2  b 2.5
3  3 3  c 3.0
4  3 4  d 3.5
5  3 5  e 4.0
6  5 2  f 3.5
7  5 3  g 4.0
8  5 4  h 4.5
9  5 5  i 5.0
10 5 6  j 5.5

3

这里是另一种可能的解决方案,使用 for 循环。我几天前遇到了同样的问题(有更多的数据集),其他解决方案不起作用。 假设您有 n 个数据集:

df1 <- data.frame(start = seq(0,20,10), stop = seq(10,30,10), ID = letters[24:26])
df2 <- data.frame(start = seq(0,20,10), stop = seq(10,30,10), ID = letters[1:3])
...
dfn <- data.frame(start = seq(0,20,10), stop = seq(10,30,10), ID = letters[n:n+2])

第一步是列出数据框的清单:

df.list<-lapply(1:n, function(x) eval(parse(text=paste0("df", x)))) #In order to store all datasets in one list using their name
names(df.list)<-lapply(1:n, function(x) paste0("df", x)) #Adding the name of each df in case you want to unlist the list afterwards

接下来,你可以使用for循环(这是最重要的部分):

for (i in 1:length(df.list)) {
  df.list[[i]][["Avg"]]<-rowMeans(df.list[[i]][1:2])
}

如果你的列表只包括前两个数据集,则会出现以下情况:

> df.list
[[1]]
  start stop ID Avg
1     0   10  x   5
2    10   20  y  15
3    20   30  z  25

[[2]]
  start stop ID Avg
1     0   10  a   5
2    10   20  b  15
3    20   30  c  25

最后,如果您希望将修改过的数据集从列表中返回到全局环境中,可以执行以下操作:

list2env(df.list,.GlobalEnv)

这种技术可以应用于n个数据集和其他函数。我认为这是最灵活的解决方案。


当我尝试将数据框存储为列表时,使用以下代码会出现“NA/NaN参数”错误: df.list<-lapply(1:n, function(x) eval(parse(text=paste0("df", x)))) - thentangler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接