2014-10-20 49 views
0

我不知道如果衝突的軟件包不是我自己的軟件包,處理掩蔽的最佳方式是否正確地衝突。考慮下面的例子。我在時間系列 上工作了很多,並且通常會使用像季度,年份等函數名。所以如果我加載tisdata.table R的功能顯然取決於程序包加載的順序。如何在R包中處理掩蓋衝突的正確方法?

library(tis) 
library(data.table) 
# this masks: between, month, quarter, year 
library(TSfame) # loads TSdbi 
con <- TSconnect("somefame.db") 
# the following fails when data.table was loaded after tis 
ts1 <- TSget("somekeyInYourDB",con) 

和012get包中的TSget不再有效。我是否需要分叉包並實現一些::語法?這個例子可能是特定的,但問題很普遍。更有經驗的用戶會做什麼?

編輯:可能我需要更清楚地說明這一點。問題在於我沒有機會明確地調用該函數,因爲TSget正在調用應明確調用的函數,並假定只有這個函數。

EDIT2,將調用堆棧的要求由任賢齊棉花:

Tracing year(actualStart) on entry 
[[1]] 
TSget("kofbauindikator_total", con) 

[[2]] 
    TSget("kofbauindikator_total", con) 

[[3]] 
.local(serIDs, con, ...) 

[[4]] 
    getfame(serIDs[i], dbname[i], save = FALSE, envir = parent.frame(), 
    start = NULL, end = NULL, getDoc = FALSE) 

    [[5]] 
    year(actualStart) 

    [[6]] 
    .doTrace((function() 
    print(sys.calls()))(), "on entry") 

[[7]] 
eval.parent(exprObj) 

[[8]] 
eval(expr, p) 

[[9]] 
eval(expr, envir, enclos) 

[[10]] 
(function() 
    print(sys.calls()))() 

Error in as.POSIXlt.default(x) : 
    do not know how to convert 'x' to class 「POSIXlt」 
+1

我在這裏丟失了一些東西,因爲'TSget'不會調用任何衝突函數的'quarter'。問題(1)'TSfame'中的函數在'tis'中調用函數,但您希望它調用'data.table'中的函數,或者(2)'TSfame'中的函數有時調用函數在'tis'中,有時會在'data.table'中調用一個函數,具體取決於'search()'路徑嗎? – 2014-10-20 10:20:35

+0

問題是'TSget'確實會調用'quarter'或任何相沖突的函數。如果我不加載data.table在所有的一切工作。如果我調用data.table,則會調用這4個屏蔽函數中的一個,而不是調用tis函數。所以2)實際上正是我的問題。 – 2014-10-20 10:29:58

+1

我有一個預感,問題可能是'TSfame'應導入'TSdbi'而不是根據它(請參閱http://stackoverflow.com/q/8637993/134830),但請您提供一個示例,以再現問題,以便更容易確認這一點。 – 2014-10-20 10:34:57

回答

1

調用堆棧顯示,曖昧地命名功能,year,被稱爲getfamegetAnywhere("getfame")顯示這在fame包中找到。

packageDescription("fame")顯示fame取決於tis而不是導入它,這是問題所在。正如here所建議的那樣,向包裹維護者(Jeff Hallman)發送電子郵件是一個好主意,要求他將依賴關係更改爲導入。這可能需要一些包裝改造的,所以你也可以建議改變路線

startYear <- as.integer(year(actualStart)) 
getfame

的短期修復到

startYear <- as.integer(tis::year(actualStart)) 

(可能還有其他的像這樣的必要的修改。 )

在您等待維護人員修復時,您可以使用assignInNamespace覆蓋該功能。也就是說,在加載包之前,輸入

assignInNamespace(
    "getfame", 
    function(sernames, db, connection = NULL, save = FALSE, envir = parent.frame(), 
    start = NULL, end = NULL, getDoc = TRUE) 
    { 
    # your fixed function definition with tis::year 
    }, 
    "fame" 
) 
+0

+1非常感謝,我想我提出了一些類似於你過去對他的快速解決方案。有什麼我可以做,但等待維護者,因爲這是這樣的利基產品?你能詳細解釋一下'assignInNamespace'嗎?但回到我原來的問題:這是否意味着:等待包維護者是這裏的方式? – 2014-10-20 12:39:22

+0

要麼你使用'assignInNamespace'來重寫'getfame',要麼你分叉包並保留整個事物的副本(可能公開託管fork以便其他人可以使用它),或者說服現有的維護者修復他包。 – 2014-10-20 13:06:28

+0

最後回到這個補丁,並使用你的想法工作......所以非常感謝!剩下的問題是追捕幾個沒有從名氣輸出的功能,所以我不得不爲名人命名::: functionname,但是這個https://gist.github.com/mbannert/6584c3aa765648b987c3作品 – 2015-02-11 21:14:20