2

如果已经有答案,请原谅,但我无法从档案中完全弄清楚。

我通过 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))
}

我现在有兴趣应用此函数为尚未在数据框中创建的变量生成值。我想使用循环或类似方法来执行此操作,因为过程是相同的,尽管特定值在 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="")))
}

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

再次,如果这已经得到回答,我们深表歉意,并提前感谢您的帮助。

4

1 回答 1

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))
  }

使用数据框是一种特殊类型的列表这一事实,您可以更轻松地进行替换。我相信那是你原来的问题:

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

}

还要检查帮助页面?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)
}

这使您可以简单地做

dfanal.reshape <- func(dfanal.reshape,40)

得到想要的结果。这是因为您的变量的名称是yearenter,adoptyearyearleave。据我所知,您必须在函数中更改yearenterintoobsyear,但这是一个细节。

学习使用索引将为您节省很多挫败感。如果添加一个参数就可以了,请永远不要再创建 40 个相同的函数。

于 2011-10-30T10:06:45.427 回答