R语言 如何在不同的数据集上创建一个循环?

hwamh0ep  于 2023-04-18  发布在  其他
关注(0)|答案(3)|浏览(167)

我需要你的帮助。我想在不同的数据集上运行一个代码。它们被称为dfQB,dfRB,dfOL,dfFB,dfWR,dfTE,dfST,dfDB,dfLB,dfDL和dfDE。我有这个代码。是否可以添加第二个循环,为上面提到的每个数据集执行此代码?非常感谢帮助!

for(i in 1:nrow(df)){
  ecdf_fun <- function(x,perc) ecdf(x)(perc)
  de=df[i,5:10]
  a=(1-ecdf_fun(df$Forty,de[1]))
  b=(ecdf_fun(df$Vertical,de[2]))
  c=(ecdf_fun(df$BenchReps,de[3]))
  d=(ecdf_fun(df$BroadJump,de[4]))
  e=(1-ecdf_fun(df$Cone,de[5]))
  f=(1-ecdf_fun(df$Shuttle,de[6]))
  nenner=6-sum(is.na(a), is.na(b),is.na(c), is.na(d),is.na(e), is.na(f))
  if (is.na(a)) {a <- 0}
  if (is.na(b)) {b <- 0}
  if (is.na(c)) {c <- 0}
  if (is.na(d)) {d <- 0}
  if (is.na(e)) {e <- 0}
  if (is.na(f)) {f <- 0}
  df$RAS[i]=((a+b+c+d+e+f)/nenner)*10
}

得到适当的帮助!

jq6vz3qz

jq6vz3qz1#

首先,避免在全局环境中将许多类似结构的 Dataframe 作为单独的对象维护。相反,store such similar data frames in a list。从那里,您可以在列表中运行lapply,以统一应用于任何定义的或用户定义的方法。

# NAMED LIST OF DFS
fb_position_dfs <- list(
   QB=dfQB, RB=dfRB, OL=dfOL, FB=dfFB, WR=dfWR, TE=dfTE, 
   ST=dfST, DB=dfDB, LB=dfLB, DL=dfDL, DE=dfDE
)

# REMOVE SEPARATE OBJECTS
rm(dfQB, dfRB, dfOL, dfFB, dfWR, dfTE, dfST, dfDB, dfLB, dfDL, dfDE)

# USER-DEFINED METHOD
df_proc <- function(df) {
  for(i in 1:nrow(df)){ 
    ecdf_fun <- function(x,perc) ecdf(x)(perc) 
    de=df[i,5:10] 
    a=(1-ecdf_fun(df$Forty,de[1]))
    b=(ecdf_fun(df$Vertical,de[2]))
    c=(ecdf_fun(df$BenchReps,de[3])) 
    d=(ecdf_fun(df$BroadJump,de[4])) 
    e=(1-ecdf_fun(df$Cone,de[5])) 
    f=(1-ecdf_fun(df$Shuttle,de[6]))
    nenner=6-sum(is.na(a), is.na(b),is.na(c), is.na(d),is.na(e), is.na(f)) 

    if (is.na(a)) {a <- 0}
    if (is.na(b)) {b <- 0} 
    if (is.na(c)) {c <- 0} 
    if (is.na(d)) {d <- 0} 
    if (is.na(e)) {e <- 0} 
    if (is.na(f)) {f <- 0} 
 
    df$RAS[i]=((a+b+c+d+e+f)/nenner)*10 
  }
  return(df)
}

# ITERATE THROUGH DFS APPLYING METHOD
new_fb_position_dfs <- lapply(fb_position_dfs, df_proc)

如果 Dataframe 碰巧源自按位置拆分的主 Dataframe ,请使用bytapply的面向对象 Package 器)对拆分应用用户定义方法:

# ITERATE THROUGH SPLITS OF DF AND APPLY METHOD
new_fb_position_dfs <- by(fb_master_df, fb_master_df$position, df_proc)
zlhcx6iw

zlhcx6iw2#

您可以将data.frames放在一个列表中,并使用purrr::map迭代每个元素。

# install.packages("purrr")

library(purrr)

datasets <- list(
  dfQB,
  dfRB,
  dfOL,
  dfFB,
  dfWR,
  dfTE,
  dfST,
  dfDB,
  dfLB,
  dfDL,
  dfDE
)

# `map` returns a list with the result of calling the function (second argument)
# with each element of the first argument (`datasets`).
datasets_transformed <- map(
  datasets,
  \(df) {
    for(i in 1:nrow(df)){
      ecdf_fun <- function(x,perc) ecdf(x)(perc)
      de=df[i,5:10]
      a=(1-ecdf_fun(df$Forty,de[1]))
      b=(ecdf_fun(df$Vertical,de[2]))
      c=(ecdf_fun(df$BenchReps,de[3]))
      d=(ecdf_fun(df$BroadJump,de[4]))
      e=(1-ecdf_fun(df$Cone,de[5]))
      f=(1-ecdf_fun(df$Shuttle,de[6]))
      nenner=6-sum(is.na(a), is.na(b),is.na(c), is.na(d),is.na(e), is.na(f))
      if (is.na(a)) {a <- 0}
      if (is.na(b)) {b <- 0}
      if (is.na(c)) {c <- 0}
      if (is.na(d)) {d <- 0}
      if (is.na(e)) {e <- 0}
      if (is.na(f)) {f <- 0}
      df$RAS[i]=((a+b+c+d+e+f)/nenner)*10
    }
    
    df
  }
)
57hvy0tb

57hvy0tb3#

如果您不打算将 Dataframe 分配给列表,另一种方法是简单地在向量中列出 Dataframe 名称,并在lapply()函数中使用get()从父环境访问对象。
如果没有一个最小的可重复的示例,执行此操作的代码看起来如下所示:

dfList <- c("dfQB","dfRB","dfOL") # a subset of the data frames

updatedData <- lapply(dfList,function(x){
     df <- get(x) # get the actual data from parent environment 
     for(i in 1:nrow(df)){
          ecdf_fun <- function(x,perc) ecdf(x)(perc)
          de=df[i,5:10]
          a=(1-ecdf_fun(df$Forty,de[1]))
          b=(ecdf_fun(df$Vertical,de[2]))
          c=(ecdf_fun(df$BenchReps,de[3]))
          d=(ecdf_fun(df$BroadJump,de[4]))
          e=(1-ecdf_fun(df$Cone,de[5]))
          f=(1-ecdf_fun(df$Shuttle,de[6]))
          nenner=6-sum(is.na(a), is.na(b),is.na(c), is.na(d),is.na(e), is.na(f))
          if (is.na(a)) {a <- 0}
          if (is.na(b)) {b <- 0}
          if (is.na(c)) {c <- 0}
          if (is.na(d)) {d <- 0}
          if (is.na(e)) {e <- 0}
          if (is.na(f)) {f <- 0}
          df$RAS[i]=((a+b+c+d+e+f)/nenner)*10
     }
     df # return to parent environment 
})

此时,对象updatedData是 Dataframe 的列表。
作为最小的可复制的例子,我们将下载和更新一列从九代神奇宝贝统计。
首先,我们将下载数据并将其解压缩到当前工作目录的子目录中。

download.file("https://raw.githubusercontent.com/lgreski/pokemonData/master/PokemonData.zip",
              "pokemonData.zip",
              method="curl",mode="wb")
   unzip("pokemonData.zip",exdir="./pokemonData")

接下来,我们将创建一个包含下载的.csv文件的vector。

thePokemonFiles <- list.files("./pokemonData",pattern = ".csv",
                              full.names=TRUE)

接下来,我们使用文件名向量将数据读入 Dataframe ,并通过assign()函数将它们分配为全局环境中的 Dataframe 。是的,我知道它是easier to work with the data frames in a list,但这复制了原始帖子的“当前状态”。

pokemonDataFiles <- lapply(thePokemonFiles,function(x) {
     df <- read.csv(x,stringsAsFactors=FALSE)
     dfName <- substr(x,15,19)
     assign(dfName,df,envir = .GlobalEnv) # assign to global environment 
})

接下来,我们将创建一个向量来表示我们创建的数据框的名称。
最后,我们在每个 Dataframe 中将HP stat乘以10,将 Dataframe 返回到列表中,并比较一个 Dataframe 的原始数据和更新数据。

theNames <- paste0("gen0",1:9)
updatedData <- lapply(theNames,function(df){
     x <- get(df)
     x$HP <- x$HP * 10 
     x
})
# compare the first few rows of gen01 Pokemon HP
head(data.frame(original.HP = gen01$HP,updatedHP =updatedData[[1]][["HP"]]))

...和输出:

> head(data.frame(original.HP = gen01$HP,updatedHP = updatedData[[1]][["HP"]]))
  original.HP updatedHP
1          45       450
2          60       600
3          80       800
4          39       390
5          58       580
6          78       780

相关问题