knitr与交互式R行为

Mat*_*lle 6 interactive r knitr

在我注意到knitr的作者建议的方法获得更多帮助后,我在这里重新发布我的问题.

我对.Rmd文件有点困惑,我可以在交互式R会话中逐行进行,也可以使用R CMD BATCH,但在使用时失败knit("test.Rmd").我不确定问题出在哪里,我试图尽可能地缩小问题范围.以下是示例(in 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)
```
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

发生错误后直接在R控制台中使用调用按预期工作...

问题与format产生ID(在apply呼叫中ltraj2sldf)的方式有关,就在ID 100,000之前:使用交互式呼叫,R给出"99994","99995","99996","99997","99998"," 99999","100000"; 使用knitr R给出"99994","99995","99996","99997","99998","99999","100000",以及额外的前导空格.

这种行为是否有任何原因发生?为什么knitr行为与R中的直接调用不同?我不得不承认我很难用那个,因为我无法调试它(它在交互式会话中工作)!

任何提示都将非常感激.我可以提供.RData如果它有帮助(文件是4.5 Mo),但我最感兴趣的是为什么会出现这种差异.我没有成功地尝试提出一个自我重现的例子,抱歉.在此先感谢您的贡献!


在评论了baptiste之后,这里有一些关于ID生成的更多细节.基本上,通过apply调用在数据帧的每一行生成ID ,而这又使用format如下:format(dfi["id"], scientific = FALSE).这里,列id只是从1到行数(1:nrow(df))的系列.scientific = FALSE只是为了确保我没有100e的1e + 05等结果.

基于对ID生成的探索,仅针对在第一消息中呈现的那些问题发生问题,即99995至99999,其中添加了前导空间.这次format调用不应该发生这种情况,因为我没有要求输出中的特定数字位数.例如:

> format(99994:99999, scientific = FALSE)
[1] "99994" "99995" "99996" "99997" "99998" "99999"
Run Code Online (Sandbox Code Playgroud)

但是,如果ID是以块的形式生成的,则可能会发生:

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

请注意,一次处理一个相同的结果会产生预期结果:

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

最后,就像ID一次没有准备好一样(正如我期望的那样apply,逐行调用),但在这种情况下,一次只有6个,而且只有接近1e + 05 ...当然,只有在使用knitr时,才能使用交互式或批量R.


这是我的会话信息:

> 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
Run Code Online (Sandbox Code Playgroud)

Mat*_*lle 0

感谢 Aleksey Vorona 和 Duncan Murdoch,这个错误现已在 R-devel 中修复!

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