我在从R中的循环返回数据帧时遇到问题。我有一组函数可以读入文件并将它们转换为数据框,供更大的项目使用/可视化。
我有一个要传递的文件名列表:
populateFrames <- function(){
for (frame in frameList){
if (exists(frame) && is.data.frame(get(frame))){
# do nothing
}
else {
frame <- clean_data(gather_data(frame))
}
}
}
此函数遍历列表并运行函数以创建数据框(如果它们尚不存在)。
# manually create "apples" data frame
apples <- clean_data(gather_data(frameList[1]))
执行时,该函数运行时没有错误,但不会将任何数据帧保存到环境中。
我可以手动运行相同的东西并保存数据框:
# returns a data frame, "apples" to the environment
assign(x = frame[1], value = clean_data(gather_data(frame[1])))
从我在这里阅读类似的问题,我看到assign()用于类似的事情。但是和以前一样,我可以手动运行代码;但是当放入循环内部时,没有数据框保存到环境中。
seqno
答案 0 :(得分:1)
解决方案,遵循“尽可能少地改变OP实施”的原则。
这里有两个问题。
frame
语句中重新分配else
以将其重新分配给frameList中的该元素。不是。这是不推荐*的方法,在函数的父环境中分配变量。在这种情况下,您将 populatingFrames 作为副作用,改变父环境中的frameList
。如果你想练习防御性编程,那么你想要避免改变输入。
populateFrames <- function(){
for (i in seq_along(frameList)){
if (exists(frameList[[i]]) && is.data.frame(get(frameList[[i]]))){
# do nothing
}
else {
frameList[[i]] <<- clean_data(gather_data(frameList[[i]]))
}
}
}
这是RECOMMENDED版本,您可以在其中返回新的frameList(这意味着您必须将其分配给值)。
populateFrames <- function(){
for (i in seq_along(frameList)){
if (exists(frameList[[i]]) && is.data.frame(get(frameList[[i]]))){
# do nothing
}
else {
frameList[[i]] <- clean_data(gather_data(frameList[[i]]))
}
}
frameList
}
答案 1 :(得分:1)
避免全局变量赋值,这通常是禁忌,尝试lapply:
lapply(
frameList,
function(frame){
if(exists(frame) && is.data.frame(get(frame))){
frame
}else{
clean_data(gather_data(frame))
}
}
)