2017-05-18 4 views
0

私は1ヶ月の賃料を計算できるR関数を作成しようとしています。引数にはstart_date、end_date、current monthがあります。そして、賃貸日の整数出力を月に返します。 (これはアパートレンタルモデルのコンテキストで使用されます)。例えば賃料日数関数

library(lubridate) 

start_date <- ymd('2017-06-15') 
end_date <- ymd('2018-06-14') 
current_month <- ymd('2017-06-01') 

rent_days_in_month(start_date, end_date, current_month) 
[1] 16 

私は作品を考える機能を持っているが、それは過度に複雑そうです。また、これがベクター化されていることを確認したいので、私はmutateを使ってデータフレームに適用することができます。ここで

は私の機能である:

rent_days_in_month <- function(start_date, 
           end_date, 
           current_month){ 

    last_day_in_month <- ceiling_date(current_month, 
            unit = "months") - 1 

    current_month_days_in_moth <- days_in_month(current_month) 

    first_day_in_month <- floor_date(current_month, 
            unit = "month") 

    if (last_day_in_month < start_date) { 

    rent_days_in_month <- 0 

    return(rent_days_in_month) 

    } 

    rent_days_in_month <- as.numeric(end_date - start_date + 1) 

    rent_days_in_month <- min(rent_days_in_month, 
          current_month_days_in_moth) 


    if (end_date < last_day_in_month){ 

    if (end_date > first_day_in_month){ 

     if (start_date > first_day_in_month) { 

     rent_days_in_month <- end_date - start_date - 1 

     return(rent_days_in_month) 

     } else { 

     rent_days_in_month <- end_date - first_day_in_month 

     return(rent_days_in_month) 
     } 

    } else { 

     rent_days_in_month <- 0 

     return(rent_days_in_month) 

    } 

    } 

    return(rent_days_in_month) 

} 

私はそれがこれを好きベクトル化作ってみました:

v_rent_days_in_month <- Vectorize(rent_days_in_month) 

は、これよりも単純に働くだろうそこにはありますか?また、Vectorize関数を適切に使用するかどうかを知りたい

おかげ

+0

あなたの機能は何ですか?私は、あなたの例であなたが「16」に到着したことを見ていません。 –

+0

あなたが指定した引数を使って書いた関数は '16'ではなく' 30'を吐き出します! –

+0

ありがとうYannis、あなたは正しいです!私の機能は機能していません。評価のためにリース開始日、リース終了日、および月を取る予定です。次に、請求される賃料の適用日を返すことになっています。それは30ではなく16でなければなりません。 –

答えて

0
library(lubridate) 
start_date <- as.Date("2017-06-15") 
end_date <- as.Date("2018-06-14") 
current_month<- as.Date("2017-06-01") 

rent_days_in_month = function(start_date, end_date, current_month){ 
    if(month(current_month) == month(start_date) & year(current_month) == year(start_date)){ 
    return(as.numeric(difftime(ceiling_date(start_date, "month"), start_date, units = c("days")))) 
    }else if(current_month < floor_date(start_date, "month") | current_month >= ceiling_date(end_date)){ 
    return("invalid date") 
    }else if(month(current_month) == month(end_date) & year(current_month) == year(end_date)){ 
    return(as.numeric(difftime(end_date, current_month, units = c("days"))) + 1) 
    }else{ 
    tmp = ceiling_date(current_month, "month") - 1 
    return(day(tmp)) 
    } 

} 

> rent_days_in_month(start_date, end_date, current_month) 
[1] 16 

> rent_days_in_month(start_date, end_date, as.Date("2015-01-01")) 
[1] "invalid date" 

> rent_days_in_month(start_date, end_date, as.Date("2018-01-01")) 
[1] 31 

> rent_days_in_month(start_date, end_date, as.Date("2018-06-01")) 
[1] 14 
+0

クリストファーソン、ありがとう。これは私が試みているのとまったく同じように働くようです!また、data.frameでmutateを扱うと思いますか?再度、感謝します! –

+0

@ChrisKiniry正直なところ、突然変異を使ったことはありません。私はそれについてのヘルプファイルをすばやく見ましたが、なぜそれがうまくいかないのか分かりません。それが失敗した場合は、ショットをつけてポストバックしてください。 – Kristofersen

+0

もし私がそうするならば、それはmutateを使ってdata.frameで動作するようです:v_rent_days_in_month < - Vectorize(rent_days_in_month) –

0
library(lubridate) 
start_date <- as.Date('2017-06-15') 
end_date <- as.Date('2018-06-14') 
days <- seq(start_date, end_date, by= 'days') 
lapply(split(days, month(days)), length) 

はすべて当時のベクトルを取得するために、=「日」で引数でseq機能を使用してください。次に、月と合計でリストに分割します。