r - 从 R 中的 data.frame 创建新类

标签 r

我正在研究 R 中的函数、类和方法。 为了进行也可能有用的“实践”练习,我决定创建我的“一揽子计划”来照顾我的家庭预算。 简而言之,我想要一系列函数、类和方法来计算东西,绘制不同类型的图表等等。 我想做的第一件事是创建一个“预算”类:这应该接受具有某些列的 csv 并返回一个对象“预算”,该对象继承数据框的相同方法,但我可以对其应用一组“预算”方法。 这是我的看法

prepareData = function (csv, type=1) {

if (type == 1) {
Data = read.csv(csv,dec = ".")}
else if (type == 2) {
Data = read.csv2(csv,dec = ",")}
else {stop ("Accetable value for type are 1 and 2")}

NamesToHave = c("Date","Title","Amount","Category")

if (sum(as.numeric(colnames(Data) %in% NamesToHave)) < 4) {
    stop ("The csv file has not the mandatory columns (Data, Title, Amount, Category)")}




if (class(try(tolower(Data$Title),silent = T)) == "try-error" | class(try(tolower(Data$Category),silent = T)) == "try-error") {
    stop("Are you sure there are no special character in your csv file ?")} 

Data$Day = sapply(strsplit(as.character(Data$Date), "/"),"[[",1)
Data$Month = month.abb[as.numeric(sapply(strsplit(as.character(Data$Date), "/"),"[[",2))]
Data$Year = sapply(strsplit(as.character(Data$Date), "/"),"[[",3)

Data = Data[with(Data, order(Year, Month, Day)), ]
Data$Amount = as.character(Data$Amount)
Data$Amount = as.numeric(as.character(Data$Amount))

class(Data) <- append(class(Data),"Budget")
return(Data)
}

现在,这会返回一个包含所有必要修改的数据框,总的来说,它作为一个函数工作得很好,但如果我按如下方式获取 csv

structure(list(Date = structure(c(22L, 1L, 1L, 1L, 1L, 1L), .Label = c("01/10/2016", 
"01/11/2016", "02/10/2016", "04/10/2016", "04/11/2016", "05/10/2016", 
"05/11/2016", "06/10/2016", "06/11/2016", "07/10/2016", "08/10/2016", 
"08/11/2016", "09/10/2016", "09/11/2016", "10/10/2016", "10/11/2016", 
"11/10/2016", "12/11/2016", "14/10/2016", "16/10/2016", "18/10/2016", 
"20/09/2016", "20/10/2016", "21/10/2016", "22/09/2016", "22/10/2016", 
"23/09/2016", "23/10/2016", "25/09/2016", "25/10/2016", "26/09/2016", 
"26/10/2016", "27/10/2016", "28/10/2016", "29/10/2016", "30/10/2016"
), class = "factor"), Title = structure(c(20L, 6L, 36L, 29L, 
30L, 11L), .Label = c("Bagpiper", "beer debaser", "Br", "brewdog", 
"Burger King", "Clas", "coop", "Coop", "Eriksdalbadet", "etc", 
"ETC", "Flippin", "Fotografiska", "Gateau Agneta", "Grekisk fastfood", 
"Grill", "Gunnarson", "Gunnarsson", "hemkop", "HK", "Hotorhallen", 
"ICA", "ICA Skinnskat", "Igor Sport", "Intersport", "Kak", "klattercentret", 
"LullesFagel", "Mae Thai", "MamaWolf", "Material", "Matrerial", 
"Oriental Supermarket", "Paradiset", "Pendeltag Uppsala", "PGW", 
"Pressbyran", "Primeburger", "Primo Ciao ciao", "R Asia", "Systembolaget", 
"taxi Skinnskat", "The Cure drinks", "Udden pensionat", "Ugglan", 
"Wentzels hobby"), class = "factor"), Amount = c(167.27, 331, 
971, 99, 192, 3289), Category = structure(c(10L, 3L, 3L, 6L, 
6L, 3L), .Label = c("Drink", "extra", "Extra", "Extra_Fede", 
"extra_food", "Extra_food", "extra_laure", "Extra_Laure", "food", 
"Food"), class = "factor")), .Names = c("Date", "Title", "Amount", 
"Category"), row.names = c(NA, 6L), class = "data.frame")

然后我就跑了

Data = prepareData("name.csv")
class(Data)

输出只是“data.frame”。但是,如果我然后从终端再次运行该函数的倒数第二行

class(Data) <- append(class(Data),"Budget")
class(Data)

我得到了“data.frame”和“Budget”作为输出。

我做错了什么?

最佳答案

您的问题在这里:

if (as.numeric(colnames(Data) %in% NamesToHave) != 4) {}

第一次比较将被矢量化执行并返回 TRUE TRUE TRUE TRUE ,这将变成 1 1 1 1当消失时扔as.numeric() 。然后,该向量将与 != 4 进行比较,执行向量化并返回 TRUE TRUE TRUE TRUE (所有的“一个”都不同于“四个”)。 if()` 语句不会评估整个向量,只会评估它的第一个元素(并向您抛出警告消息)。

要解决此问题,您只需切换 as.numeric()函数为 sum()

if (sum(colnames(Data) %in% NamesToHave) != 4) {}

当对逻辑向量求和时,R将其强制转换为数字: all TRUE成为1以及所有FASLE成为0 。现在您将得到 4 个总和,其值为 FALSE在if语句中,函数运行顺利。一旦我解决了这个问题,当我第一次运行它时它就有了两个类。

正如 this article 中所述,重启就好了R在发布您的问题之前,请确保您仍然遇到所报告的问题。

关于r - 从 R 中的 data.frame 创建新类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40596773/

相关文章:

r - ggplot2 错误消息 : Error in seq. default(range[1], range[2], length.out = nframes): 'from' 必须是有限数

r - 使用 data.table 通过多个键进行子集化的奇怪行为

r - 使用 stargazer 进行生活并出现错误

r - 带有 ggplot2 的轮廓文本

r - 计算可变长度话语中最终单词的频率列表

r - 如何将 pivot_longer 与 name_pattern 一起使用

r - 在 Mac 上将 R 连接到 Filemaker Pro 15

r - 如何在整个数据框中找到最小值的索引?

r - 如何从 Ensembl 检索染色体上基因的起始值和终止值

R:我如何为每个级别(用于 reshape )创建一个带有订单数(按日期)的新变量。)