簡體   English   中英

從R中的data.frame創建新類

[英]Create new class from data.frame in R

我正在玩弄R中的功能,類和方法。為了進行“實踐”練習也很有用,我決定創建我的“包”以照顧我的家庭預算。 簡單地說,我想要一系列函數,類和方法來計算東西,繪制不同類型的圖表,什么不是。 我想要做的第一件事就是創建一個“預算”類:這應該包含一個帶有某些列的csv並返回一個對象“Budget”,該對象繼承了數據框的相同方法,但我可以向其應用一組“預算”方法。 這是我的看法

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 ,當拋出as.numeric()時將變為1 1 1 1 然后,將該矢量與!= 4進行比較,執行矢量化並返回TRUE TRUE TRUE TRUE (所有'一個與四個不同)。 if()`語句不會評估整個向量,只是它的第一個元素(並向你發出一條警告信息)。

要解決此問題,您只需將as.numeric()函數切換為sum()

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

當你對邏輯向量求和時, R會將它強制轉換為數字:所有TRUE變為1 ,所有FASLE變為0 現在,您將獲得在if語句中評估為FALSE的4和,以及它運行順暢的函數。 一旦我解決了它,它在我第一次運行它時就有兩個類。

正如本文所述,在發布問題之前重啟R並確保您仍然遇到報告問題是很好的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM