R:生成变量名,评估函数列表中的函数,并将这些值分配给循环中生成的变量名

SMM*_*SMM 2 loops for-loop r variable-names dataframe

如果已有答案,请原谅我,但我无法从档案中找到答案.

我通过R中的for循环生成了一个非常相似的函数列表:

adoptint.fun=list()
    for(i in 1:40) {
    #function name for each column
    func.name <- paste('adoptint',i,sep='')
    #function
    func = paste('function(yearenter, adoptyear, yearleave) {ifelse(is.na(yearenter) | yearenter >', i+1905, ' | is.na(adoptyear) | yearleave > ', i+1905, ', NA, ifelse(yearenter <= ', i+1905, ' & adoptyear <= ', i+1905, ', 1, 0))}', sep='')
    adoptint.fun[[func.name]] = eval(parse(text=func))
}
Run Code Online (Sandbox Code Playgroud)

我现在有兴趣应用此函数为尚未在数据框中创建的变量生成值.我想使用循环或类似方法来做这个,因为过程是相同的,尽管特定值在40次迭代中发生变化.代码看起来像:

#generate variables that will be inserted into dataframe, dfanal.reshape
var_names <- paste("dfanal.reshape$adopt", 1:40, sep="")

#run function i to obtain values for variable i, which should be appended to dataframe
for(i in 1:40){
    var_names[i] <- eval(parse(paste("adoptint.fun[[" ,i, "]](dfanal.reshape$intoobsyear,dfanal.reshape$adoptyear,dfanal.reshape$yearleave)", sep="")))
}
Run Code Online (Sandbox Code Playgroud)

我已经使用了mget for var_names段,但这似乎不起作用,并且eval段也不起作用(即,没有将函数确定的值(工作正常)分配给适当的dataframe列.

如果这已经得到回答,请再次表示歉意,并提前感谢您的帮助.

Jor*_*eys 7

如何为函数添加额外的参数?

func <- function(yearenter, adoptyear, yearleave,i) {
  ifelse(is.na(yearenter) | yearenter > i+1905 | is.na(adoptyear) | yearleave >  i+1905 , NA, 
         ifelse(yearenter <=  i+1905 & adoptyear <=  i+1905, 1, 0))
  }
Run Code Online (Sandbox Code Playgroud)

使用数据帧是一种特殊的列表这一事实,这将允许您更轻松地进行替换.这是我相信的原始问题:

for(i in 1:40){
  varname <- paste('adopt',i,sep='')
  dfanal.reshape[[varname]] <- 
    with(dfanal.reshape,
         func(intoobsyear,adoptyear,yearleave,i)
    )

}
Run Code Online (Sandbox Code Playgroud)

另请查看帮助页面?which?Extract

现在没有可重复的例子(参见如何制作一个很好的R可重复的例子?),很难猜测你想做什么以及如何更经济地做到这一点.你还在使用大量的计算时间.以下功能可能会执行您想要的操作:

func <- function(df,j){
  out <- matrix(0,nrow=nrow(df),ncol=j)
  attach(df)
  idna <- sapply(1:j,function(i)
    is.na(yearenter) | yearenter > i+1905 | is.na(adoptyear) | yearleave >  i+1905
    )
  out[idna] <- NA
  id1 <- sapply(1:j,function(i)
    yearenter <=  i+1905 & adoptyear <=  i+1905
    )
  out[id1] <- 1
  detach(df)
  colnames(out)<- paste('adopt',1:j,sep='')
  cbind(df,out)
}
Run Code Online (Sandbox Code Playgroud)

这可以让你简单地做

dfanal.reshape <- func(dfanal.reshape,40)
Run Code Online (Sandbox Code Playgroud)

获得理想的结果.这是因为变量的名称是yearenter,adoptyearyearleave.据我所看到的,你必须改变yearenter,以intoobsyear在功能,但是这是一个细节.

学习使用指数将为您节省很多挫折感.并且,如果添加一个参数,它永远不会再次发出40个相同的函数.