2016-11-14 6 views
3

Rの関数、クラス、メソッドを使いこなしています "手を使って"練習をすることも有益なので、私は "パッケージ"を作成することにしました。私の家計の世話をしています。 簡単に言えば、私は物事を計算するための一連の関数、クラス、メソッドを必要とします。 最初にやりたいことは、「予算」クラスを作成することです。これは特定の列を含むCSVを取り込み、データフレームの同じメソッドを継承するが、セットを適用できるオブジェクト「予算」を返す必要がありますの "予算"メソッドの。ここ は私のテイクは今、これはすべての必要な修正を加えたデータフレームを返すRクラスのdata.frameから新しいクラスを作成する

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"です。しかし、端末から関数の最後の2行目から2番目の行を再度実行すると、出力として「data.frame」と「Budget」が取得されました。

私は間違っていますか?

+0

投稿した例にいくつかの問題があるため、問題を再現できませんでした。どうぞ、[この記事](http://stackoverflow.com/help/mcve)をご覧ください。 –

+0

問題を再現できません。オブジェクトに正しいクラスが両方あるように見えます。 –

+0

私が知っているのは、不思議なことに、関連のない問題(以下の答えを参照)を修正したときに問題が解決されるということです。トマスが言うように、Rを再起動することが時々役立つかもしれません。 –

答えて

2

あなたの問題はここにあった:

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

最初comparationが行わベクトル化と1 1 1 1なくなって投げas.numeric()になるであろう、TRUE TRUE TRUE TRUEを返します。次に、このベクトルは!= 4と比較され、ベクトル化されて実行され、TRUE TRUE TRUE TRUE(すべて1が4と異なる)が返されます。 if() `文はベクトル全体を評価しません。最初の要素です(警告メッセージを表示します)。

この問題を解決するには、as.numeric()機能をsum()に切り替えるだけで済みます。あなたは論理ベクトルを合計すると

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

Rは、数値にそれを強制します:すべてのTRUE1になり、すべてのFASLE0なります。これで、if文でFALSEと評価される4つの合計と、それが円滑に実行される関数が得られます。私がそれを解決すると、最初にそれを実行すると、両方のクラスがあります。

this articleに記載されているように、質問を投稿する前にRを再起動して、問題がまだ報告されていることを確認してください。

+0

本当にありがとう、私は私の例を修正していた間に同じことを見つけました。 しかし、自分自身を改善するためのフォローアップとして、これを最小限の再現可能な例にするというあなたの意見に欠けていたものは何ですか? 私はデータとコードを入れましたが、私は何ができましたか? いずれにしても、ありがとう! –

+0

関数自体の前で扱ったすべての事例を知る必要はありませんでした(最初のすべてのif-elses)。実際、問題を投稿する前にそれらを取り除いた場合、クラスを割り当てることではなく、起こりうるエラーを処理することに問題があることがわかります。 –

+0

よろしいですか。 フィードバックありがとうございます! –

関連する問題