如果对此已经有答案,请原谅,但是我不能从文件中找出答案。
我已经通过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段也无法正常工作(即,未将函数确定的值(可以正常工作)分配给适当的dataframe列。
再次致歉,如果已回答您,请在此先感谢您的帮助。
最佳答案
如何在函数中添加额外的参数?
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
现在没有可重现的示例(请参见How to make a great R reproducible example?),很难猜测您想要做什么以及如何更经济地进行操作。您仍在使用大量计算时间。以下功能可能会满足您的要求:
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
,adoptyear
和yearleave
。据我所知,您必须在函数中将yearenter
更改为intoobsyear
,但这很详细。学习使用索引将为您节省很多挫败感。而且,请不要再添加40个相同的函数(如果添加一个参数)。