例如,假设我想构建一个用于分析客户交易的包。在一个美好的世界中,每个交易数据集都看起来像
TransactionId CustomerId TransactionDate
1: 1 1 2017-01-01
2: 2 2 2017-01-15
3: 3 1 2017-05-20
4: 4 3 2017-06-11
然后我可以做出像
这样的好功能num_customers <- function(transactions){
length(unique(transactions$CustomerId))
}
实际上,人们使用的列名称各不相同。 (例如,“CustomerId”,“CustomerID”和“cust_id”可能都被不同公司使用)。
我的问题是,对我来说,最好的方法是什么?我计划严重依赖data.table,所以我的直觉是让用户提供从列名到我用作表的属性的映射的映射,如
mytransactions <- data.table(
transaction_id = c(1L, 2L, 3L, 4L),
customer_id = c(1L, 2L, 1L, 3L),
transaction_date = as.Date(c("2017-01-01", "2017-01-15", "2017-05-20", "2017-06-11"))
)
setattr(
mytransactions,
name = "colmap",
value = c(TransactionID="transaction_id", CustomerID="customer_id", TransactionDate="transaction_date")
)
attributes(mytransactions)
然而,遗憾的是,只要他们对数据进行子集化,就会删除此属性。
attributes(mytransactions[1:2])
答案 0 :(得分:0)
如果您希望数据具有特定形状和属性集,请定义类。使用S3系统在R中操作非常简单,因为您只需要更改class
属性。
让用户创建S3对象的最佳方法是通过一个函数。保持原有的感觉&#34;在调整现有数据集时,让用户提供数据集并命名要用于不同值的列。默认参数值可以使您的包裹代码简明扼要并奖励尊重用户的标准。
transaction_table <- function(dataset,
cust_id = "CustomerId",
trans_id = "TransactionId",
trans_date = "TransactionDate") {
keep_columns <- c(
CustomerId = cust_id,
TransactionId = trans_id,
TransactionDate = trans_date
)
out_table <- dataset[, keep_columns, with = FALSE]
setnames(out_table, names(keep_columns))
setattr(out_table, "class", c("transaction_table", class(out_table)))
out_table
}
standardized <- transaction_table(
mytransactions,
cust_id = "customer_id",
trans_id = "transaction_id",
trans_date = "transaction_date"
)
standardized
# CustomerId TransactionId TransactionDate
# 1: 1 1 2017-01-01
# 2: 2 2 2017-01-15
# 3: 1 3 2017-05-20
# 4: 3 4 2017-06-11
作为奖励,您现在可以充分利用S3系统,为通用功能定义特定于类的方法。
print.transaction_table <- function(x, ...) {
time_range <- range(standardized[["TransactionDate"]])
formatted_range <- strftime(time_range)
cat("Transactions from", formatted_range[1], "to", formatted_range[2], "\n")
NextMethod()
}
print(standardized)
# Transactions from 2017-01-01 to 2017-06-11
# CustomerId TransactionId TransactionDate
# 1: 1 1 2017-01-01
# 2: 2 2 2017-01-15
# 3: 1 3 2017-05-20
# 4: 3 4 2017-06-11