首页 \ 问答 \ 当我使用函数创建属性时,如何向R data.frame添加属性?(How do I add an attribute to an R data.frame while I'm making it with a function?)

当我使用函数创建属性时,如何向R data.frame添加属性?(How do I add an attribute to an R data.frame while I'm making it with a function?)

假设我有一个R data.frame:

> x <- data.frame()

我还有一个用sprintf()构建的SQL查询:

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

我打算将这个包含在一个函数中,以便用query的结果填充data.frame x ,并且只是为了在顶部填充一些我想告诉我未来的自我使用什么query来生成data.frame x 。 我想通过调用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"

因为该功能看起来像

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
               }

稍后我将能够做到以下几点

> 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"

Let's say I have an R data.frame:

> x <- data.frame()

I also have a SQL query I am building with sprintf():

> (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. I'd like to do this with a call to attr() like so:

> 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"

原文:https://stackoverflow.com/questions/42217741
更新时间:2020-02-28 15:53

最满意答案

请注意,R中的数据库函数通常会返回一个数据框,因此您不必填充空的现有数据框。 下面我们使用sqldf包来保持示例自包含且可重现,但您可以替换正在使用的任何类型的数据库访问。 (通常,您需要创建一个数据库连接并将其传递给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")

赠送:

> 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"

引用类使用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()

赠送:

> 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"

Note that database functions in R typically return a data frame so you don't have to fill an empty existing one. 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. (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.)

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 :

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"
2017-02-14

相关文章

更多

最新问答

更多
  • css在元素之前中断列而不破坏包装器(css break column before element without breaking the wrapper)
  • 如何在Xamarin共享项目中使用自定义渲染器(How to use Custom Renderer in Xamarin Shared Project)
  • 如何为特定表中的特定字段设置唯一?(How to set unique for specific field from specific table?)
  • Google SDK iOS - sign()方法完成处理程序(Google SDK iOS - sign() method completion handler)
  • 在具有接口{}值的地图上实现String()(Implement String() on a map with interface{} values)
  • 检查数据库中是否已存在用户名(Check if username already exist in DB)
  • 使用javascript进行ajax调用时阻止用户交互(Block user interaction while doing ajax call using javascript)
  • 什么'if(err)'在Javascript中精确测试?(What does 'if (err)' tests precisely in Javascript?)
  • jQuery mouseleave无法正常工作(jQuery mouseleave not working)
  • 寻求使用的一些说明(Seeking some clarification on use of )
  • 将数组传递给注释的语法(syntax for passing array to annotation)
  • 用于从两个日期范围之间的文件中提取数据的Shell脚本(Shell script to extract data from file between two date ranges)
  • 元素隐藏但父()没有(Element hides but parent() not)
  • 如何使用Google App Engine Java平台开发web ui(How to develop web ui with Google App Engine Java platform)
  • 对于OWL A级;(For an OWL class A; Getting all properties that A is their domain)
  • Excel VBA公式格式问题(Excel VBA Formula Format Issue)
  • ORA - 02287序列号不允许在这里(ORA - 02287 sequence number not allowed here)
  • Github拉忽略特定文件(Github Pull Ignore Specific File)
  • SQL CONVERT函数在SQL Server中工作但不在应用程序中(SQL CONVERT function working in SQL Server but not in application)
  • backbone.js适用于大型应用程序(backbone.js for large applications)
  • 防止程序关闭(Preventing program from closing)
  • 生成不带图像的heightMap(Generating a heightMap without an Image)
  • Bootstrap - 如何将包含文本的div居中?(Bootstrap - How to center div that has text inside it?)
  • Android - 片段findViewById()总是null?(Android - Fragment findViewById() always null?)
  • 确定CSS中的高度(Figuring out heights in CSS)
  • 使用__autoload包含类和使用命名空间(Use __autoload to include class and use namespace)
  • setTimeout()不允许我传递文本值[重复](setTimeout() doesn't allow me to pass text values [duplicate])
  • 在NSUserDefault中恢复值(Restoring value in NSUserDefault)
  • 知道如何将这种下沉的悬停效果添加到图像/链接吗?(Any idea how to add this sinking hover effect to an image/link?)
  • 在XIB中淡入/淡出UISegmentedControl(fade in/fade out UISegmentedControl in XIB)