0

已经提出了类似的问题,但没有一个能够解决我的具体问题。我有一个.R包含许多基本微积分的文件(“Mycalculus.R”),我需要将其应用于数据框的子集:每年的一个子集,其中“年”的模态是因子(yearA、yearB、yearC)而不是数值. 该文件生成一个新的数据框,我需要将其保存在 Rda 文件中。这是我希望代码看起来像一个for循环(这个显然不起作用):

id <- identif(unlist(df$year))
for (i in 1:length(id)){
    data <- subset(df, year == id[i])
    source ("Mycalculus.R", echo=TRUE)
    save(content_df1,file="myresults.Rda")
}

这是主要data.frame df的确切信息:

obs    year    income    gender   ageclass    weight
 1     yearA    1000       F         1          10
 2     yearA    1200       M         2          25
 3     yearB    1400       M         2           5
 4     yearB    1350       M         1          11

以下是源文件“Mycalculus.R”的作用:它将许多基本微积分应用于称为“数据”的数据帧的列,并基于 df1 创建两个新数据帧 df1 和 df2。这是一个摘录:

data <- data %>% 
   group_by(gender) %>% 
   mutate(Income_gender = weighted.mean(income, weight))
data <- data %>% 
   group_by(ageclass) %>% 
   mutate(Income_ageclass = weighted.mean(income, weight))

library(GiniWegNeg)
gini=c(Gini_RSV(data$Income_gender, weight), Gini_RSV(data$Income_ageclass,weight))

df1=data.frame(gini)
colnames(df1) <- c("Income_gender","Income_ageclass")
rownames(df1) <- c("content_df1")

df2=(1/5)*df1$Income_gender+df2$Income_ageclass
colnames(df2) <- c("myresult")
rownames(df2) <- c("content_df2")

所以最后,我得到了两个这样的数据框:

                    Income_Gender  Income_Ageclass    
content_df1           ....             ....     

对于 df2:

                    myresult      
content_df2           ....          

但我需要将 df1 和 Rf2 保存为 Rda 文件,其中 content_df1 和 content_df2 的行名按子集给出,如下所示:

                    Income_Gender  Income_Ageclass    
content_df1_yearA     ....             ....     
content_df1_yearB     ....             ....     
content_df1_yearC     ....             ....     

                    myresult
content_df2_yearA     ....   
content_df2_yearB     ....    
content_df2_yearC     ....   

目前,我的程序不使用任何循环并且正在完成这项工作,但很混乱。基本上代码是2500多行代码。(请不要向我扔西红柿)。

任何人都可以帮助我解决这个特定的要求吗?先感谢您。

4

2 回答 2

2

考虑将所有内容与所需参数的已定义函数合并到一个脚本中,由lapply(). 然后,Lapply 返回一个数据帧列表,您可以将这些数据帧绑定到一个最终的 df 中。

library(dplyr)
library(GiniWegNeg)

runIncomeCalc <- function(data, y){      
  data <- data %>% 
    group_by(gender) %>% 
    mutate(Income_gender = weighted.mean(income, weight))
  data <- data %>% 
    group_by(ageclass) %>% 
    mutate(Income_ageclass = weighted.mean(income, weight))      

  gini <- c(Gini_RSV(data$Income_gender, weight), Gini_RSV(data$Income_ageclass,weight))

  df1 <- data.frame(gini)
  colnames(df1) <- c("Income_gender","Income_ageclass")
  rownames(df1) <- c(paste0("content_df1_", y))

  return(df1)
}

runResultsCalc <- function(df, y){
  df2 <- (1/5) * df$Income_gender + df$Income_ageclass
  colnames(df2) <- c("myresult")
  rownames(df2) <- c(paste0("content_df2_", y)

  return(df2)
}

dfIncList <- lapply(unique(df$year), function(i) {      
  yeardata <- subset(df, year == i)
  runIncomeCalc(yeardata, i)      
})

dfResList <- lapply(unique(df$year), function(i) {      
  yeardata <- subset(df, year == i)
  df <- runIncomeCalc(yeardata, i) 
  runResultsCalc(df, i)      
})

df1 <- do.call(rbind, dfIncList)
df2 <- do.call(rbind, dfResList)

现在,如果您需要跨脚本获取资源。在 Mycalculus.R 中创建相同的两个函数runIncomeCalcrunResultsCalc,然后在其他脚本中调用它们:

library(dplyr)
library(GiniWegNeg)

if(!exists("runIncomeCalc", mode="function")) source("Mycalculus.R")

dfIncList <- lapply(unique(df$year), function(i) {      
  yeardata <- subset(df, year == i)
  runIncomeCalc(yeardata, i)      
})

dfResList <- lapply(unique(df$year), function(i) {      
  yeardata <- subset(df, year == i)
  df <- runIncomeCalc(yeardata, i) 
  runResultsCalc(df, i)      
})

df1 <- do.call(rbind, dfIncList)
df2 <- do.call(rbind, dfResList)
于 2016-08-03T22:22:18.890 回答
1

如果您将步骤功能化,则可以创建如下工作流:

calcFunc <- function(df) {
  ## Do something to the df, then return it
  df
}

processFunc <- function(fname) {
  ## Read in your table
  x <- read.table(fname)

  ## Do the calculation
  x <- calcFunc(x)

  ## Make a new file name (remember to change the file extension)
  new_fname <- sub("something", "else", fname)

  ## Write the .RData file
  save(x, file = new_fname)
}

### Your workflow
## Generate a vector of files
my_files <- list.files()

## Do the work
res <- lapply(my_files, processFunc)

或者,不要保存文件。省略 ,save中的调用processFunc并返回 data.frame 对象列表。然后使用data.table::rbindlist(res)do.call(rbind, list)来制作一个大的 data.frame 对象。

于 2016-08-03T18:20:48.953 回答