我在 R 中有一個涉及 S4 類系統的晦澀問題。
首先,我創建一個 tibble 并保存它:
df = tibble::tibble(a=1:5, b=2:6)
save(df, file="foo.Rdata")
接下來,我關閉 R 會話,并開始一個新會話(出于某種原因,這很重要)。
然后,我定義了一個 S4 方法,該方法在 a data.frame(atibble是其子類)上進行調度:
setGeneric("sumTheColumns", function(target){
standardGeneric("sumTheColumns")
})
setMethod("sumTheColumns", signature(target="data.frame"), function(target){
colSums(target)
})
load("foo.Rdata")
print(df)
print(class(df))
print(showMethods(sumTheColumns))
sumTheColumns(df)
由此,R 輸出:
[1] "sumTheColumns"
a b
1 1 2
2 2 3
3 3 4
4 4 5
5 5 6
[1] "tbl_df" "tbl" "data.frame"
Function: sumTheColumns (package .GlobalEnv)
target="data.frame"
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘sumTheColumns’ for signature ‘"tbl_df"’
Calls: sumTheColumns -> <Anonymous>
Execution halted
如您所見,tibble正在正確保存和加載,并保留其類,但不再正確分派。有趣的是,如果您在我們創建的第一個 R 會話中定義和呼叫這些相同的方法,這些方法會df正確調度。
為什么會發生這種情況,我該如何解決?
如果這是特定于作業系統的錯誤,以下是一些輸出sessionInfo:
> sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-conda-linux-gnu (64-bit)
Running under: Ubuntu 21.04
uj5u.com熱心網友回復:
比較loadedNamespaces()兩種情況下的條目。我明白
> loadedNamespaces()
[1] "compiler" "graphics" "utils" "grDevices" "stats" "datasets" "methods" "base"
在一個干凈的新會話中,但在創建后df,它增長到
> loadedNamespaces()
[1] "compiler" "magrittr" "ellipsis" "graphics" "pillar" "glue" "utils"
[8] "tibble" "grDevices" "crayon" "stats" "utf8" "fansi" "datasets"
[15] "vctrs" "methods" "lifecycle" "pkgconfig" "rlang" "base"
所以這些新軟體包之一解決了這個問題。我猜是它tibble本身,確實我在新會話中看到了錯誤,但在我運行之后沒有看到loadNamespace("tibble")(它獲取了第二個串列中的所有內容)。所以一個解決方案是:
為了讓你的資料框方法在小標題上作業,你可以運行
loadNamespace("tibble")
在給他們打電話之前。如果您打算將 tibbles 視為其他地方的 tibbles,您可能想要這樣做,例如讓它們以 tibbles 列印的方式列印。
或者,如果您只是希望您的代碼像資料幀一樣處理 tibbles,您可以執行tibble包的操作,然后運行
methods::setOldClass(c("tbl_df", "tbl", "data.frame"))
這不會加載任何包,但它會告訴 S4 系統小標題從資料幀繼承。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/394681.html
上一篇:在組內創建具有恒定值的亂數
下一篇:從R中的值開始編號
