在使用函数创建属性时,如何向 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()
我还有一个 SQL 正在使用 sprintf() 构建的查询:
> (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"
请注意,R 中的数据库函数通常 return 一个数据框,因此您不必填充一个空的现有数据框。下面我们使用 sqldf 包来保持示例 self-contained 和可重现性,但您可以替换您正在使用的任何类型的数据库访问。 (通常您需要创建数据库连接并将其传递给 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的引用classes我们可以定义一个class包含数据和查询字段以及存储查询的方法和 运行 这样每个输出对象都使用 .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"
假设我有一个 R data.frame:
> x <- data.frame()
我还有一个 SQL 正在使用 sprintf() 构建的查询:
> (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"
请注意,R 中的数据库函数通常 return 一个数据框,因此您不必填充一个空的现有数据框。下面我们使用 sqldf 包来保持示例 self-contained 和可重现性,但您可以替换您正在使用的任何类型的数据库访问。 (通常您需要创建数据库连接并将其传递给 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的引用classes我们可以定义一个class包含数据和查询字段以及存储查询的方法和 运行 这样每个输出对象都使用 .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"