2016-02-11 52 views
0

我正在創建一個函數,但我需要一些最佳實踐方面的幫助。執行測試,從同一行的另一列獲取結果

Active.Test <- function(date) { 
    date <- rep(date,length(df$Start.Date)) 
    active <- rep(0,length(df$Start.Date)) 


    active[date > df$Start.Date & date < df$End.Date] <- 1 
    active[df$Start.Date == df$End.Date ] <- df$Active.Time 
    return (active) 
} 

我基本上要檢查的日期(這是傳遞給函數)是我的數據幀的開始和結束日期之間。如果是,則分配一個1.如果開始日期和結束日期相等,則從Active.Time列中的同一行獲取結果。其他值的默認值爲0.

這將返回一個錯誤,因爲它將檢索第二個測試的大小不同的向量。

我可以重新編寫上面:

Active.Test <- function(date) { 
    date <- rep(date,length(df$Start.Date)) 
    active <- rep(0,length(df$Start.Date)) 


    active[date > df$Start.Date & date < df$End.Date] <- 1 
    active[df$Start.Date == df$End.Date] <- df$Active.Time[df$Start.Date == df$End.Date] 
    return (active) 
} 

那麼這將讓來自Active.Time柱正確的元素,但這似乎並沒有被寫這一種優雅的方式。我也猜測這是慢的,因爲我執行同樣的檢查兩次多次。

你能幫我用最佳實踐重新寫這個嗎?

編輯:這裏有一些代碼來獲取幾行數據,然後通過檢查是否開始和結束日期包含25/05/2016來測試使用函數。

#Create a data frame 
df <- data.frame(End.Date = as.Date(c("1/05/2016","28/05/2016", "25/05/2016"), format = "%d/%m/%Y"), Start.Date = as.Date(c("20/04/2016 11:00","20/05/2016 23:00", "25/05/2016 10:00"), format = "%d/%m/%Y"), Active.Time = as.numeric(c(0.5,0.4,0.8))) 

#Test the function 
df$new <- Active.Test(as.Date("25/05/2016", format = "%d/%m/%Y")) 

感謝

+0

提供一個最小的數據集,人們可以馬上處理。 – shekeine

+0

感謝您的評論。增加了一些數據。 – user1923975

回答

0
# Using the data.table approach 
library(data.table) 

# Make data table instead of data.frame (you can also do as.data.table(df) to get a data.table) 
my_dt <- data.table(Start.Date=as.Date(c("20/04/2016 11:00","20/05/2016 23:00", "25/05/2016 10:00"), format = "%d/%m/%Y"), 
        End.Date=as.Date(c("1/05/2016","28/05/2016", "25/05/2016"), format = "%d/%m/%Y"), 
        Active.Time = as.numeric(c(0.5,0.4,0.8)) 
        ) 
setkey(my_dt) 

# Sample date to test 
datte <- as.Date("25/05/2016", format = "%d/%m/%Y") 

# Create function with conditions and result to return 
Active.Test <- function(datte, Start.Date, End.Date, Active.Time) { 

    if(datte > Start.Date & datte < End.Date){ 
    return(1) 
    } 
    else if(Start.Date==End.Date){ 
    return(Active.Time) 
    } 
    else{return(0)} 

    } 

# Test function 
my_dt[, res:=Active.Test(datte, Start.Date, End.Date, Active.Time), by=1:nrow(my_dt)] 

更多關於data.tabledata.table vignette。另外,在上面的函數中,請注意您在運行df$new <- Active.Test(as.Date("25/05/2016", format = "%d/%m/%Y"))時得到的警告!

+0

我試圖避免嵌入功能,因爲我的條件數量可能會增加。 – user1923975

+0

所有條件必須在某處指定,不能轉義。實現上述解決方案的更好方法是將所有條件放入與之前類似的函數中。然後函數可以(a)以編輯的答案中顯示的方式傳遞給data.table,或者(b)用'apply(...,MARGIN = 1)'循環遍歷數據框/矩陣的行。這兩個選項,如舊答案中的選項都不會「輸入」輸入參數。看data.table的小插曲爲什麼data.table解決方案是「更好的做法」:特別是':='操作符和鍵。 – shekeine

相關問題