简体   繁体   English

使用函数创建属性时如何在R data.frame中添加属性?

[英]How do I add an attribute to an R data.frame while I'm making it with a function?

Let's say I have an R data.frame: 假设我有一个R data.frame:

> x <- data.frame()

I also have a SQL query I am building with sprintf(): 我也有一个使用sprintf()构建的SQL查询:

> (query <- sprintf("select %s from %s %s", "names", "name_table", "where age > 20"))
[1] "select names from name_table where age > 20"

I intend to encase this in in a function in order to fill the data.frame x with the results from query , and just for a few sprinkles on top I want to tell my future self what query was used to generate the data.frame x . 我打算将其包含在一个函数中,以便用query的结果填充data.frame x ,而只是在上面撒了几下,我想告诉我未来的自我,什么query用于生成data.frame x I'd like to do this with a call to attr() like so: 我想通过这样调用attr()来做到这一点:

> attr(x, "query") <- query
> str(x)
'data.frame':   0 obs. of  0 variables
 - attr(*, "query")= chr "select names from name_table where age > 20"

Because the function is going to look something like 因为该函数看起来像

answer_maker <- function(col_names, table_name, condtions) {

                   query <- sprintf("select %s from %s %s", col_names, table_name, conditions)

                   data.frame(sql(query))

    ############## WHAT DO I DO HERE? 
    ############## I want to type something py-like ...self.attr()?
                   attr(self, "query") <- query
               }

Later on I will be able to do the following 稍后,我将能够执行以下操作

> my_first_answer <- answer_maker("names", "name_table", "where age > 20")
> attr(my_first_answer, "query")
[1] "select names from name_table where age > 20"

Note that database functions in R typically return a data frame so you don't have to fill an empty existing one. 请注意,R中的数据库函数通常返回一个数据帧,因此您不必填充现有的空数据帧。 Below we use the sqldf package to keep the example self-contained and reproducible but you can substitute whatever sort of database access you are using. 下面,我们使用sqldf程序包使该示例保持独立和可复制,但是您可以替换所使用的任何类型的数据库访问。 (Typically you will need to create a data base connection and pass it into answer_maker but in this example since we are using sqldf it was not needed.) (通常,您将需要创建一个数据库连接并将其传递到answer_maker但是在此示例中,由于我们使用的是sqldf,因此不需要它。)

library(sqldf)   
name_table <- data.frame(names = letters, age = 1:26) # test data

answer_maker <- function(col_names, table_name, conditions) {
      query <- sprintf("select %s from %s %s", col_names, table_name, conditions)
      ans <- sqldf(query)
      attr(ans, "query") <- query
      ans
}

ans <- answer_maker("names", "name_table", "where age > 20")

giving: 赠送:

> ans
  names
1     u
2     v
3     w
4     x
5     y
6     z

> attr(ans, "query")
[1] "select names from name_table where age > 20"

Reference Classes Using R's reference classes we can define a class with data and query fields and methods which store the query and run it such that each outputs the object using .self : 参考类使用R的参考类,我们可以定义一个带有数据和查询字段以及存储查询并运行查询的方法的类,这样每个查询都使用.self输出对象:

Query <- setRefClass("Query", fields = c("data", "query"),
   methods = list(
      setQuery = function(col_names, table_name, conditions) {
          query <<- sprintf("select %s from %s %s", col_names, table_name, conditions)
          .self
      },
      runQuery = function() {
          data <<- sqldf(query)
          .self
      }))

qq <- Query$
        new()$
        setQuery("names", "name_table", "where age > 20")$
        runQuery()

giving: 赠送:

> qq$data
  names
1     u
2     v
3     w
4     x
5     y
6     z
> qq$query
[1] "select names from name_table where age > 20"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM