7

MNP不幸な呼び出しdeparse(最大幅が500文字に制限されている) をトレースしたパッケージで問題が発生しています。

背景(退屈している場合は簡単にスキップできます)

mnpやや特異な構文を使用してさまざまな選択肢セット(数式定義に含める)を使用できるためcbind(choiceA,choiceB,...)、数式呼び出しの左側は、呼び出し時に1700文字程度model.matrix.defaultdeparseなります。deparse最大width.cutoff500文字をサポートするため、の行sapply(attr(t, "variables"), deparse, width.cutoff = 500)[-1L]model.matrix.default最初の要素として次のようになります。

[1] "cbind(plan1, plan2, plan3, plan4, plan5, plan6, plan7, plan8, plan9, plan10, plan11, plan12, plan13, plan14, plan15, plan16, plan17, plan18, plan19, plan20, plan21, plan22, plan23, plan24, plan25, plan26, plan27, plan28, plan29, plan30, plan31, plan32, plan33, plan34, plan35, plan36, plan37, plan38, plan39, plan40, plan41, plan42, plan43, plan44, plan45, plan46, plan47, plan48, plan49, plan50, plan51, plan52, plan53, plan54, plan55, plan56, plan57, plan58, plan59, plan60, plan61, plan62, plan63, "       
[2] "    plan64, plan65, plan66, plan67, plan68, plan69, plan70, plan71, plan72, plan73, plan74, plan75, plan76, plan77, plan78, plan79, plan80, plan81, plan82, plan83, plan84, plan85, plan86, plan87, plan88, plan89, plan90, plan91, plan92, plan93, plan94, plan95, plan96, plan97, plan98, plan99, plan100, plan101, plan102, plan103, plan104, plan105, plan106, plan107, plan108, plan109, plan110, plan111, plan112, plan113, plan114, plan115, plan116, plan117, plan118, plan119, plan120, plan121, plan122, plan123, "
[3] "    plan124, plan125, plan126, plan127, plan128, plan129, plan130, plan131, plan132, plan133, plan134, plan135, plan136, plan137, plan138, plan139, plan140, plan141, plan142, plan143, plan144, plan145, plan146, plan147, plan148, plan149, plan150, plan151, plan152, plan153, plan154, plan155, plan156, plan157, plan158, plan159, plan160, plan161, plan162, plan163, plan164, plan165, plan166, plan167, plan168, plan169, plan170, plan171, plan172, plan173, plan174, plan175, plan176, plan177, plan178, plan179, "
[4] "    plan180, plan181, plan182, plan183, plan184, plan185, plan186, plan187, plan188, plan189, plan190, plan191, plan192, plan193, plan194, plan195, plan196, plan197, plan198, plan199, plan200, plan201, plan202, plan203, plan204, plan205, plan206, plan207, plan208, plan209, plan210, plan211, plan212, plan213, plan214, plan215, plan216, plan217, plan218, plan219, plan220, plan221, plan222, plan223, plan224, plan225, plan226, plan227, plan228, plan229, plan230, plan231, plan232, plan233, plan234, plan235, "
[5] "    plan236, plan237, plan238, plan239, plan240, plan241, plan242, plan243, plan244, plan245, plan246, plan247, plan248, plan249, plan250, plan251, plan252, plan253, plan254, plan255, plan256, plan257, plan258, plan259, plan260, plan261, plan262, plan263, plan264, plan265, plan266, plan267, plan268, plan269, plan270, plan271, plan272, plan273, plan274, plan275, plan276, plan277, plan278, plan279, plan280, plan281, plan282, plan283, plan284, plan285, plan286, plan287, plan288, plan289, plan290, plan291, "
[6] "    plan292, plan293, plan294, plan295, plan296, plan297, plan298, plan299, plan300, plan301, plan302, plan303, plan304, plan305, plan306, plan307, plan308, plan309, plan310, plan311, plan312, plan313)"  

これmodel.matrix.defaultをdata.frame内の変数に対してテストすると、エラーが返されます。

問題

これを回避するために、私は新しいdeparse関数を作成しました。

deparse <- function (expr, width.cutoff = 60L, backtick = mode(expr) %in% 
  c("call", "expression", "(", "function"), control = c("keepInteger", 
                                                        "showAttributes", "keepNA"), nlines = -1L)  {
    ret <- .Internal(deparse(expr, width.cutoff, backtick, .deparseOpts(control), nlines))
    paste0(ret,collapse="")
  }

ただし、mnp再度実行してステップスルーすると、同じ理由で同じエラーが返されます(base::deparse実行中ですが、実行中deparseです)。

ユーザー定義関数が一時的に基本関数を上書きするこの例では、私が期待するものがより典型的であるため、これは私にはいくぶん驚くべきことです。

> print <- function() {
+   cat("user-defined print ran\n")
+ }
> print()
user-defined print ran

この問題を解決する正しい方法は書き直すことmodel.matrix.defaultだと思いますが、デバッグ用のツールとして、自分を使用するように強制する方法とdeparse、予期された(私が)動作がここで発生しない理由に興味があります。

4

2 に答える 2

4

関数fixInNamespaceと関数assignInNamespaceは、既存の関数を編集できるように提供されています。あなたは試すことができます...しかし、いじるのはあまりにも危険に見えるので、私はしません:deparse

 assignInNamespace("deparse", 
                  function (expr, width.cutoff = 60L, backtick = mode(expr) %in% 
               c("call", "expression", "(", "function"), control = c("keepInteger", 
               "showAttributes", "keepNA"), nlines = -1L)  {
    ret <- .Internal(deparse(expr, width.cutoff, backtick, .deparseOpts(control), nlines))
    paste0(ret,collapse="")
                         }   , "base")

ヘルプページには、そのような機能の使用には制限があるという指示があり、そのようなコア機能に追加の保護層があることに驚かないでしょう. 副作用によって機能するため、結果を割り当てる必要はありません。

于 2012-05-20T16:08:35.293 に答える
3

これは、セクション 1.6, R拡張機能の記述のパッケージ名前空間で説明されているように、名前空間を持つパッケージが関数を検索する方法です。

名前空間は、ロードされると封印されます。シーリングとは、インポートとエクスポートを変更できず、内部変数バインディングを変更できないことを意味します。封印により、名前空間メカニズムの実装戦略がより単純になります。また、シーリングにより、コード分析およびコンパイル ツールは、関数本体内のグローバル変数参照に対応する定義を正確に識別できます。

名前空間は、パッケージ内の関数で使用される変数の検索戦略を制御します。ローカルで見つからない場合、R は最初にパッケージの名前空間を検索し、次にインポート、次にベース名前空間、次に通常の検索パスを検索します。

于 2012-05-20T15:56:50.900 に答える