6

私は、より多くの助けを得るために、knitr の作成者によってアドバイスされたアプローチであることに気づいた後、ここに私の問題を再投稿しています。

インタラクティブな R セッションで .Rmd ファイルを 1 行ずつ進めることがR CMD BATCHでき、knit("test.Rmd"). どこに問題があるのか​​わからないので、できる限り問題を絞り込もうとしました。次に例を示します ( test.Rmd)。

```{r Rinit, include = FALSE, cache = FALSE}
opts_knit$set(stop_on_error = 2L)
library(adehabitatLT)
```

The functions to be used later:

```{r functions}
ld <- function(ltraj) {
    if (!inherits(ltraj, "ltraj")) 
        stop("ltraj should be of class ltraj")
    inf <- infolocs(ltraj)
    df <- data.frame(
        x = unlist(lapply(ltraj, function(x) x$x)),
        y = unlist(lapply(ltraj, function(x) x$y)),
        date = unlist(lapply(ltraj, function(x) x$date)),
        dx = unlist(lapply(ltraj, function(x) x$dx)),
        dy = unlist(lapply(ltraj, function(x) x$dy)),
        dist = unlist(lapply(ltraj, function(x) x$dist)),
        dt = unlist(lapply(ltraj, function(x) x$dt)),
        R2n = unlist(lapply(ltraj, function(x) x$R2n)),
        abs.angle = unlist(lapply(ltraj, function(x) x$abs.angle)),
        rel.angle = unlist(lapply(ltraj, function(x) x$rel.angle)),
        id = rep(id(ltraj), sapply(ltraj, nrow)),
        burst = rep(burst(ltraj), sapply(ltraj, nrow)))
    class(df$date) <- c("POSIXct", "POSIXt")
    attr(df$date, "tzone") <- attr(ltraj[[1]]$date, "tzone")
    if (!is.null(inf)) {
        nc <- ncol(inf[[1]])
        infdf <- as.data.frame(matrix(nrow = nrow(df), ncol = nc))
        names(infdf) <- names(inf[[1]])
        for (i in 1:nc) infdf[[i]] <- unlist(lapply(inf, function(x) x[[i]]))
        df <- cbind(df, infdf)
    }
    return(df)
}
ltraj2sldf <- function(ltr, proj4string = CRS(as.character(NA))) {
    if (!inherits(ltr, "ltraj")) 
        stop("ltr should be of class ltraj")
    df <- ld(ltr)
    df <- subset(df, !is.na(dist))
    coords <- data.frame(df[, c("x", "y", "dx", "dy")], id = as.numeric(row.names(df)))
    res <- apply(coords, 1, function(dfi) Lines(Line(matrix(c(dfi["x"], 
        dfi["y"], dfi["x"] + dfi["dx"], dfi["y"] + dfi["dy"]), 
        ncol = 2, byrow = TRUE)), ID = format(dfi["id"], scientific = FALSE)))
    res <- SpatialLinesDataFrame(SpatialLines(res, proj4string = proj4string), 
        data = df)
    return(res)
}
```

I load the object and apply the `ltraj2sldf` function:

```{r fail}
load("tr.RData")
juvStp <- ltraj2sldf(trajjuv, proj4string = CRS("+init=epsg:32617"))
dim(juvStp)
```

使用knitr("test.Rmd")は次のように失敗します:

label: fail
Quitting from lines 66-75 (test.Rmd) 
Error in SpatialLinesDataFrame(SpatialLines(res, proj4string = 
proj4string),  (from     <text>#32) : 
  row.names of data and Lines IDs do not match

エラーが発生した後にRコンソールで直接呼び出しを使用すると、期待どおりに機能します...

この問題は、ID 100,000 の直前に( の呼び出しで) formatID を生成する方法に関連しています: 対話型呼び出しを使用すると、R は "99994"、"99995"、"99996"、"99997"、"99998"、" 99999"、"100000"; Knitr R を使用すると、"99994"、" 99995"、" 99996"、" 99997"、" 99998"、" 99999"、"100000" が得られ、先頭にスペースが追加されます。applyltraj2sldf

この動作が発生する理由はありますか? knitrRでの直接呼び出しとは異なる動作をする必要があるのはなぜですか? 私はそれをデバッグすることができないので、私はそれで苦労していることを認めなければなりません (対話型セッションで動作します)!

どんなヒントでも大歓迎です。役立つ場合は .RData を提供できます (ファイルは 4.5 Mo です)。自己再現可能な例を考え出すことに成功しませんでした。申し訳ありません。貢献してくれてありがとう!


baptiste のコメントに続いて、ID 生成に関する詳細をいくつか示します。apply基本的に、ID は呼び出しによってデータ フレームの各行で生成され、次のformatように使用されますformat(dfi["id"], scientific = FALSE)。ここで、列idは単純に 1 から行数 ( 1:nrow(df)) までの系列です。scientific = FALSE100000 に対して 1e+05 などの結果が得られないようにするためです。

ID 生成の調査に基づいて、問題は最初のメッセージ、つまり先頭にスペースが追加された 99995 から 99999 に表示されたものに対してのみ発生しました。format出力で特定の桁数を要求しなかったため、この呼び出しではこれは発生しません。例えば:

> format(99994:99999, scientific = FALSE)
[1] "99994" "99995" "99996" "99997" "99998" "99999"

ただし、ID がチャンクで生成される場合は、次のことが発生する可能性があります。

> format(99994:100000, scientific = FALSE)
[1] " 99994" " 99995" " 99996" " 99997" " 99998" " 99999" "100000"

一度に 1 つずつ同じ処理を行うと、期待どおりの結果が得られることに注意してください。

> for (i in 99994:100000) print(format(i, scientific = FALSE))
[1] "99994"
[1] "99995"
[1] "99996"
[1] "99997"
[1] "99998"
[1] "99999"
[1] "100000"

最終的には、ID が一度に 1 つずつ準備されていない場合とまったく同じですが (回線ごとの呼び出しから予想されるapplyように)、この場合は一度に 6 つずつ、1e+05 に近い場合のみ...もちろん、インタラクティブまたはバッチ R ではなく、knitr を使用する場合のみです。


ここに私のセッション情報があります:

> sessionInfo()
R version 3.0.1 (2013-05-16)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=fr_FR.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=fr_FR.UTF-8        LC_COLLATE=fr_FR.UTF-8    
 [5] LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=fr_FR.UTF-8   
 [7] LC_PAPER=C                 LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] knitr_1.2           adehabitatLT_0.3.12 CircStats_0.2-4    
[4] boot_1.3-9          MASS_7.3-27         adehabitatMA_0.3.6 
[7] ade4_1.5-2          sp_1.0-11           basr_0.5.3         

loaded via a namespace (and not attached):
[1] digest_0.6.3    evaluate_0.4.4  formatR_0.8     fortunes_1.5-0 
[5] grid_3.0.1      lattice_0.20-15 stringr_0.6.2   tools_3.0.1
4

3 に答える 3

2

この情報を添えて、 knitr GitHub の問題にコメントを追加しました。

format()digitsオプションが値を表示するのに十分ではなく、オプションも指定されている場合、余分な空白を追加しscientific=FALSEます。Knitr はdigits、コード ブロック内で 4 に設定されます。これにより、記述した動作が発生します。

options(digits=4)
format(99999, scientific=FALSE)

プロデュース:

[1] " 99999"

その間:

options(digits=5)
format(99999, scientific=FALSE)

プロデュース:

[1] "99999"
于 2013-07-26T02:28:58.557 に答える
0

Aleksey Vorona と Duncan Murdoch のおかげで、このバグは R-devel で修正されました!

参照: https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=15411

于 2013-08-27T03:27:47.140 に答える