如何在R函数内以编程方式创建和分配变量

时间:2022-05-16 16:55:28

I am trying to download datasets from Quandl, assign my own newly created names to the dataframes I create in the function and then save them as R.data files to be loaded back into the global environment in later sessions.

我试图从Quandl下载数据集,将我自己新创建的名称分配给我在函数中创建的数据帧,然后将它们保存为R.data文件,以便在以后的会话中加载回全局环境。

The problem I'm having is in saving the R.data file in such a way that when I reload the file it has the variable name that I want for the dataframe.

我遇到的问题是以这样的方式保存R.data文件,当我重新加载文件时,它具有我想要的数据帧的变量名称。

So for example I tried the following function:

例如,我尝试了以下功能:

retrieve_FRED_data <-
  function(dataID = Quandl_FRED_Identifier, filename = assigned_name) {
    require(Quandl)
    Quandl.api_key("xxxxxxxxxxxx")
    data <- Quandl(paste(c("FRED/", dataID), collapse = ""))
    assign(filename, data)
    save(filename, file = paste(c(filename, ".Rdata"), collapse = ""))
    return(filename)
  }

This worked to a point. I could now get a dataframe object in my functions environment that was a copy of 'data' but with the correct 'assigned_name'.

这很有用。我现在可以在我的函数环境中获取一个数据帧对象,该对象是“数据”的副本,但具有正确的“assigned_name”。

But the save function doesn't work as intended. All I've done is saved a character string variable that has the same name as the character string, not the dataframe that I had intended.

但是保存功能无法正常工作。我所做的就是保存了一个与字符串同名的字符串变量,而不是我想要的数据帧。

I've tried to modify the 'filename' argument within the save function by using 'as.name(filename)', various attempts at using the substitute function, using eval in front of substitute, etc. etc.

我试图通过使用'as.name(filename)',使用替换函数的各种尝试,在替换前使用eval等来修改save函数中的'filename'参数。

Each time I try something like this I get an error that says "as.name(filename) object not found", and similar for the other attempts.

每次我尝试这样的东西时,我都会收到一条错误,上面写着“找不到as.name(filename)对象”,其他尝试也是如此。

How can I pass my 'filename = assigned_name' function argument as an argument into the save function?

如何将'filename = assigned_name'函数参数作为参数传递给save函数?

UPDATE:

Sorry everyone, I didn't play close enough attention to Ruis' modified edit. And thanks to Aaron too, since also figured it out. The following code works perfectly:

对不起大家,我没有足够关注Ruis的修改编辑。还要感谢Aaron,因为他也想出来了。以下代码完美运行:

retrieve_FRED_data_mod <-
  function(dataID = Quandl_FRED_Identifier, filename = assigned_name) {
    require(Quandl)
    Quandl.api_key("xxxxxxxxxxxxxxx")
    data <- Quandl(paste(c("FRED/", dataID), collapse = ""))
    assign(filename, data)
    save(list = filename, file = paste0(filename, ".RData"))
    return(get(filename))
  }

2 个解决方案

#1


1  

In what follows I've commented out the Quandl related stuff just to test the save part of the code. So one of the arguments passed on to the function is a dummy argument. For your real use case remove the comment characters and it will do what you need. A file is created in the working directory and the test dataset data is saved under the argument Quandl_FRED_identifier = "x" and returned by the function.

在下面我已经注释掉了Quandl相关的东西,只是为了测试代码的保存部分。因此,传递给函数的一个参数是伪参数。对于您的真实用例,删除注释字符,它将执行您需要的操作。在工作目录中创建文件,测试数据集数据保存在参数Quandl_FRED_identifier =“x”下并由函数返回。

retrieve_FRED_data <-
  function(dataID = Quandl_FRED_Identifier, filename = assigned_name) {
#    require(Quandl)
#    Quandl.api_key("xxxxxxxxxxxx")
#    data <- Quandl(paste(c("FRED/", dataID), collapse = ""))
    assign(dataID, data)
    save(list = dataID, file = paste0(filename, ".Rdata"))
    return(get(dataID))
  }

data <- data.frame(X = 1:5, Y = 6:10)
Quandl_FRED_Identifier <- "x"  # name of the object (df) to be saved
assigned_name <- "so"    # so = *, obviously
retrieve_FRED_data(Quandl_FRED_Identifier, assigned_name)
#  X  Y
#1 1  6
#2 2  7
#3 3  8
#4 4  9
#5 5 10

Note also that you can use paste0(filename, ".RData") which is simpler but I haven't changed that part, I only did the changes strictly needed to make the function save the file.

另请注意,您可以使用更简单的paste0(文件名,“。RData”),但我没有更改该部分,我只做了严格需要的更改才能使该函数保存文件。

EDIT.
There was a missing argument list to save. It seems to be working correctly now.

编辑。有一个缺少的参数列表要保存。它现在似乎正常工作。

x
#  X  Y
#1 1  6
#2 2  7
#3 3  8
#4 4  9
#5 5 10
rm(x)
load("so.RData")
x
#  X  Y
#1 1  6
#2 2  7
#3 3  8
#4 4  9
#5 5 10

EDIT 2.
The function is creating files with objects named according to the argument passed to it. Considering the mess in the comments, I will repeat part of the code above, namely, the first call to the function. It will create a file so.RData with a df named x. The second call creates a file so2.RData with df y. Then, I remove both x and y. When the files are loaded the df's are in the globalenv as expected.

编辑2.该函数创建的文件包含根据传递给它的参数命名的对象。考虑到评论中的混乱,我将重复上面的部分代码,即第一次调用函数。它将使用名为x的df创建一个so.RData文件。第二个调用使用df y创建一个so2.RData文件。然后,我删除x和y。加载文件时,df是按照预期的方式在globalenv中。

data <- data.frame(X = 1:5, Y = 6:10)
Quandl_FRED_Identifier <- "x"  # 
assigned_name <- "so"    # so = *, obviously
retrieve_FRED_data(Quandl_FRED_Identifier, assigned_name)

set.seed(1)
data <- data.frame(A = rnorm(5), B = rnorm(5))
Quandl_FRED_Identifier <- "y"  # 
assigned_name <- "so2"    # so = *, obviously
retrieve_FRED_data(Quandl_FRED_Identifier, assigned_name)

rm(x, y)

load("so.RData")
load("so2.RData")

x
y

#2


1  

If I was to do this, I would separate it into three functions. The first reads in your data, however you do that. The second one saves a single R variable in an Rdata file with a new variable name, and the default filename is that variable name. The third one puts them together to read the data and save it with a new name, using the default of the filename being the name.

如果我这样做,我会把它分成三个功能。第一个读取数据,但是你这样做。第二个在Rdata文件中使用新变量名保存单个R变量,默认文件名是变量名。第三个将它们放在一起以读取数据并使用新名称保存它,使用文件名的默认值作为名称。

readQuandl <- function(dataID, dir="FRED") {
    Quandl.api_key("xxxxxxxxxxxx")
    Quandl(file.path(dir, dataID))
}

saveAs <- function(x, name, file=paste0(name,".RData")) {
    assign(name, x)
    save(list=name, file=file)
}

saveQuandlAs <- function(dataID, name) {
    x <- readQuandl(dataID)
    saveAs(x, name)
}

#1


1  

In what follows I've commented out the Quandl related stuff just to test the save part of the code. So one of the arguments passed on to the function is a dummy argument. For your real use case remove the comment characters and it will do what you need. A file is created in the working directory and the test dataset data is saved under the argument Quandl_FRED_identifier = "x" and returned by the function.

在下面我已经注释掉了Quandl相关的东西,只是为了测试代码的保存部分。因此,传递给函数的一个参数是伪参数。对于您的真实用例,删除注释字符,它将执行您需要的操作。在工作目录中创建文件,测试数据集数据保存在参数Quandl_FRED_identifier =“x”下并由函数返回。

retrieve_FRED_data <-
  function(dataID = Quandl_FRED_Identifier, filename = assigned_name) {
#    require(Quandl)
#    Quandl.api_key("xxxxxxxxxxxx")
#    data <- Quandl(paste(c("FRED/", dataID), collapse = ""))
    assign(dataID, data)
    save(list = dataID, file = paste0(filename, ".Rdata"))
    return(get(dataID))
  }

data <- data.frame(X = 1:5, Y = 6:10)
Quandl_FRED_Identifier <- "x"  # name of the object (df) to be saved
assigned_name <- "so"    # so = *, obviously
retrieve_FRED_data(Quandl_FRED_Identifier, assigned_name)
#  X  Y
#1 1  6
#2 2  7
#3 3  8
#4 4  9
#5 5 10

Note also that you can use paste0(filename, ".RData") which is simpler but I haven't changed that part, I only did the changes strictly needed to make the function save the file.

另请注意,您可以使用更简单的paste0(文件名,“。RData”),但我没有更改该部分,我只做了严格需要的更改才能使该函数保存文件。

EDIT.
There was a missing argument list to save. It seems to be working correctly now.

编辑。有一个缺少的参数列表要保存。它现在似乎正常工作。

x
#  X  Y
#1 1  6
#2 2  7
#3 3  8
#4 4  9
#5 5 10
rm(x)
load("so.RData")
x
#  X  Y
#1 1  6
#2 2  7
#3 3  8
#4 4  9
#5 5 10

EDIT 2.
The function is creating files with objects named according to the argument passed to it. Considering the mess in the comments, I will repeat part of the code above, namely, the first call to the function. It will create a file so.RData with a df named x. The second call creates a file so2.RData with df y. Then, I remove both x and y. When the files are loaded the df's are in the globalenv as expected.

编辑2.该函数创建的文件包含根据传递给它的参数命名的对象。考虑到评论中的混乱,我将重复上面的部分代码,即第一次调用函数。它将使用名为x的df创建一个so.RData文件。第二个调用使用df y创建一个so2.RData文件。然后,我删除x和y。加载文件时,df是按照预期的方式在globalenv中。

data <- data.frame(X = 1:5, Y = 6:10)
Quandl_FRED_Identifier <- "x"  # 
assigned_name <- "so"    # so = *, obviously
retrieve_FRED_data(Quandl_FRED_Identifier, assigned_name)

set.seed(1)
data <- data.frame(A = rnorm(5), B = rnorm(5))
Quandl_FRED_Identifier <- "y"  # 
assigned_name <- "so2"    # so = *, obviously
retrieve_FRED_data(Quandl_FRED_Identifier, assigned_name)

rm(x, y)

load("so.RData")
load("so2.RData")

x
y

#2


1  

If I was to do this, I would separate it into three functions. The first reads in your data, however you do that. The second one saves a single R variable in an Rdata file with a new variable name, and the default filename is that variable name. The third one puts them together to read the data and save it with a new name, using the default of the filename being the name.

如果我这样做,我会把它分成三个功能。第一个读取数据,但是你这样做。第二个在Rdata文件中使用新变量名保存单个R变量,默认文件名是变量名。第三个将它们放在一起以读取数据并使用新名称保存它,使用文件名的默认值作为名称。

readQuandl <- function(dataID, dir="FRED") {
    Quandl.api_key("xxxxxxxxxxxx")
    Quandl(file.path(dir, dataID))
}

saveAs <- function(x, name, file=paste0(name,".RData")) {
    assign(name, x)
    save(list=name, file=file)
}

saveQuandlAs <- function(dataID, name) {
    x <- readQuandl(dataID)
    saveAs(x, name)
}