【问题标题】:How to loop through elements of several data.frames如何遍历几个data.frames的元素
【发布时间】:2022-01-03 13:38:05
【问题描述】:

我想遍历具有相同编号或 ID 的不同 data.frame 的元素:df1、df3、df4、df66、df76,此外我们还有 pp1、pp3、pp4、pp66、pp76 和 dd1、dd3、dd4 , dd66, dd76。每个 data.frame 都有两列频率和能量:

df1 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
df3 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
df4 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
df66 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
df76 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))

pp1 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
pp3 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
pp4 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
pp66 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
pp76 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))

dd1 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
dd3 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
dd4 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
dd66 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
dd76 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))

所以首先我们创建一个 ID 向量来遍历这些数字

ID = c(1, 3, 4, 66, 76)

我试过了,很明显不行

for (i in ID){
   dfmaster[i] <-  df[i]$frequency + pp[i]$frequency + dd[i]$frequency
}

我也尝试将 paste0 用作:

for (i in ID){
   paste0("dfmaster",i) <-  paste0("df",i)+paste0("pp",i)+paste0("dd",i)}

因为这会创建一个角色。但实际上我会如何使用例如 matlab。

【问题讨论】:

  • 能否请您使问题可重现并包括预期输出的示例Link for guidance on asking questions
  • 添加到问题中的对象被命名为向量:str(df1),而不是数据帧is.data.frame(df1)frequencyenergy 是否只有一个值与每个 df# 对象关联?
  • 没有实际上应该是大约 140 个值,但为简单起见,只添加了一个值...

标签: r loops element


【解决方案1】:

@Peter 关于制作可重现示例的评论非常相关,但您的问题很清楚,可以提供一些一般性建议,尽管在没有测试数据的情况下,这都是未经测试的代码。

循环对象的“R 方式”是使用lists。您可以将独立对象放入如下列表中:

dfList <- list(df1, df3, df4, df66, df76)
ppList <- list(pp1, pp3, pp4, pp66, pp76)
ddList <- list(dd1, dd3, dd4, dd66, dd76)

虽然同时创建它们和列表会更有效。

一旦对象在列表中,您就可以编写:

dfMaster <- lapply(
              1:length(dfList),
              function(i) {
                dfList[[i]]$frequency + ppList[[i]]$frequency + ddList[[i]]$frequency
              }
            )

其中lapply将第二个参数中的函数应用到其第一个参数的每个元素并返回一个列表

或者,如果您想使用for 循环,您可以编写:

dfMaster <- list()

for(i in 1:length(dfList)) {
  dfMaster[[i]] <- dfList[[i]]$frequency + 
                     ppList[[i]]$frequency + ddList[[i]]$frequency
}

[注意这里需要在运行循环之前声明一个空列表来包含for循环的结果。]

虽然我通常会避免 for 循环,因为您很容易被 lazy evaluation 发现。

如果 ID 相关,您可以命名列表的元素;

ID <- c(1, 3, 4, 66, 76)
names(dfList) <- ID
names(ppList) <- ID
names(ddList) <- ID

dfMaster <- lapply(
  ID,
  function(i) {
    dfList[[i]]$frequency + ppList[[i]]$frequency + ddList[[i]]$frequency
  }
)

或在创建列表时命名列表的元素:

dfList <- list("1"=df1, "3"=df3, "4"=df4, "66"=df66, "76"=df76)

【讨论】:

  • 非常感谢您的建议。当我使用测试数据时,我在 for 循环中收到以下错误:错误:$ operator is invalid for atomic vectors
  • 正如@Peter 和我已经评论的那样,在没有测试数据的情况下不可能给出详细的建议。如果您提供最小可重复的示例,您将最大限度地获得有用的答案。 This post 可能会有所帮助。请阅读我们提供的链接中的建议并相应地更新您的问题。
  • 再次感谢!该问题已通过示例进行了编辑,但实际上您回答了更笼统的问题,这就是问题的目的。谢谢:D
猜你喜欢
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
  • 2021-10-04
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
  • 1970-01-01
相关资源
最近更新 更多