2013-07-25 1 views
6

Ich stelle my problem hier um, nachdem ich festgestellt habe, dass dies der Ansatz war, der von Knitrs Autor empfohlen wurde, mehr Hilfe zu bekommen.knitr vs. interactive R Verhalten

Ich bin ein bisschen Puzzle mit einer .RMD-Datei, die ich Zeile für Zeile in einer interaktiven R-Sitzung fortfahren kann, und auch mit R CMD BATCH, aber das schlägt fehl, wenn Sie knit("test.Rmd") verwenden. Ich bin mir nicht sicher, wo das Problem liegt, und ich habe versucht, das Problem so weit wie möglich einzugrenzen. Hier ist das Beispiel (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) 
``` 

knitr("test.Rmd") mit fehlschlägt Verwendung:

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 

Mit dem Anruf direkt in der R-Konsole, nachdem der Fehler aufgetreten funktioniert wie erwartet ...

Das Problem hängt mit der Art und Weise zusammen, wie format die ID (im apply Anruf von ltraj2sldf) erzeugt, kurz vor ID 100.000: Bei einem interaktiven Anruf gibt R "99994", "99995", "99996", "99997", "99998 "," 99999 "," 100000 "; mit knitr R gibt "99994", "99995", "99996", "99997", "99998", "99999", "100000", mit zusätzlichen führenden Leerzeichen.

Gibt es einen Grund für dieses Verhalten auftreten? Warum sollte sich knitr anders verhalten als ein direkter Anruf in R? Ich muss zugeben, dass ich es schwer habe, da ich es nicht debuggen kann (es funktioniert in einer interaktiven Sitzung)!

Jeder Tipp wird sehr geschätzt. Ich kann die .RData liefern, wenn es hilft (die Datei ist 4,5 Mo), aber ich bin hauptsächlich daran interessiert, warum so ein Unterschied passiert. Ich habe versucht, ohne Erfolg ein selbst reproduzierbares Beispiel zu finden, tut mir leid. Vielen Dank im Voraus für jeden Beitrag!


Nach einem Kommentar von Baptiste, hier sind einige weitere Details über IDs Generation. Grundsätzlich wird die ID bei jeder Zeile des Datenrahmens durch einen Aufruf apply generiert, der format wie folgt verwendet: format(dfi["id"], scientific = FALSE). Hier ist die Spalte id einfach eine Reihe von 1 bis zur Anzahl der Zeilen (1:nrow(df)). scientific = FALSE ist nur um sicherzustellen, dass ich keine Ergebnisse wie 1e + 05 für 100000 habe.

Basierend auf einer Untersuchung der IDs Generation, trat das Problem nur für die in der ersten Nachricht, 99995 bis 99999, für die ein führender Platz hinzugefügt wird. Dies sollte nicht mit diesem format Anruf geschehen, da ich nicht nach einer bestimmten Anzahl von Ziffern in der Ausgabe gefragt habe. Zum Beispiel:

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

Wenn jedoch die IDs in Blöcken erzeugt werden, kann es vorkommen:

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

Beachten Sie, dass die gleiche verarbeitete einer nach dem anderen das erwartete Ergebnis liefert:

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

Am Ende ist es genau so, als wären die IDs nicht einzeln vorbereitet (wie ich von einem apply Anruf per Leitung erwarten würde), aber in diesem Fall 6 zu einer Zeit, und nur wenn nahe 1e + 05 ... Ein d natürlich nur bei Verwendung von Knitr, nicht interaktiv oder Batch R.


Hier ist meine Sitzungsinformationen:

> 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 
+0

lang-shot: 'knitr' könnte einige Formatierungsoptionen ändern (zum Beispiel Anzahl der signifikanten Stellen), irgendwie zu beeinflussen, wie die IDs generiert werden. – baptiste

+0

Es könnte sein. Aber ich sehe immer noch nicht, welche Optionen diese Ausgabe beeinflussen können.Lassen Sie mich mehr Details über die Generierung von IDs in meiner ersten Nachricht hinzufügen ... Sehen Sie, ob es mehr Sinn macht! Vielen Dank. –

+0

können Sie mit diesem Formatproblem ein minimales Beispiel machen? Ich verstehe das bisschen über die Anwendung und die Leerraumauffüllung nicht. Hast du 10000 in deiner Liste oder nicht? – baptiste

Antwort

2

ich einen Kommentar zu Ihrer knitr GitHub issue mit diesen Informationen hinzugefügt.

format() fügt das zusätzliche Leerzeichen hinzu, wenn die Option digits nicht ausreicht, um einen Wert anzuzeigen, aber scientific=FALSE wird ebenfalls angegeben. knitr setzt digits-4 innerhalb Codeblöcke, die das Verhalten verursacht Sie beschreiben:

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

Produziert:

[1] " 99999" 

While:

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

Produziert:

[1] "99999" 
+0

Ganz richtig! Das hat mich dazu gebracht, das Problem so weit wie möglich einzuschränken, und "Optionen (Ziffern = X)" ist tatsächlich der Auslöser des Problems! Siehe meine Antwort unten. –

3

Sowohl Jeff als auch Baptiste waren Das war in der Tat richtig! Dies ist ein Optionsproblem, das sich auf das Argument digits bezieht. Ich schaffte es mit einem Arbeits minimal Beispiel zu kommen (zB in test.Rmd):

Simple reproducible example : df1 is a data frame of 110,000 rows, 
with 2 random normal variables + an `id` variable which is a series 
from 1 to the number of row. 

```{r example} 
df1 <- data.frame(x = rnorm(110000), y = rnorm(110000), id = 1:110000) 
``` 

From this, we create a `id2` variable using `format` and `scientific = 
FALSE` to have results with all numbers instead of scientific 
notations (e.g. 100,000 instead of 1e+05): 

```{r example-continued} 
df1$id2 <- apply(df1, 1, function(dfi) format(dfi["id"], scientific = FALSE)) 
df1$id2[99990:100010] 
``` 

Es als interaktiv mit R erwartet funktioniert, was zu:

[1] "99990" "99991" "99992" "99993" "99994" "99995" "99996" 
[8] "99997" "99998" "99999" "100000" "100001" "100002" "100003" 
[15] "100004" "100005" "100006" "100007" "100008" "100009" "100010" 

Doch die Ergebnisse sind sehr unterschiedlich mit knit :

> library(knitr) 
> knit("test.Rmd") 

[...] 

## [1] "99990" "99991" "99992" "99993" "99994" " 99995" " 99996" 
## [8] " 99997" " 99998" " 99999" "100000" "100001" "100002" "100003" 
## [15] "100004" "100005" "100006" "100007" "100008" "100009" "100010" 

Beachten Sie die zusätzlichen führenden Leerzeichen nach 99994. der Unterschied stammt tatsächlich aus dem digits Optio n, wie von Jeff richtig vorgeschlagen: R verwendet standardmäßig 7, während knitr 4 verwendet. Dieser Unterschied betrifft die Ausgabe von format, obwohl ich nicht wirklich verstehe, was hier vor sich geht. R-style:

> options(digits = 7) 
> format(99999, scientific = FALSE) 
[1] "99999" 

knitr-style:

> options(digits = 4) 
> format(99999, scientific = FALSE) 
[1] " 99999" 

Aber es soll alle Zahlen beeinflusst, nicht nur nach 99994 (na ja, um ehrlich zu sein, ich verstehe nicht einmal, warum es das Hinzufügen führenden überhaupt) Plätze:

> options(digits = 4) 
> format(c(1:10, 99990:100000), scientific = FALSE) 
[1] "  1" "  2" "  3" "  4" "  5" "  6" "  7" 
[8] "  8" "  9" " 10" " 99990" " 99991" " 99992" " 99993" 
[15] " 99994" " 99995" " 99996" " 99997" " 99998" " 99999" "100000"  

Daraus habe ich keine Ahnung, die Schuld ist: knitr, apply oder format? Zumindest habe ich einen Workaround mit dem Argument trim = TRUE in format gefunden. Es löst nicht die Ursache des Problems, aber entfernt den führenden Platz in den Ergebnissen ...

+0

nun, ich verstehe das auch nicht ganz; vielleicht ist es irgendwo dokumentiert, obwohl –

+0

Ich habe eine Nachricht an die R-Hilfe-Liste gesendet, mal sehen, ob jemand mehr Ideen dazu hat ... https://stat.ethz.ch/pipermail/r-help/2013-Juli /357642.html –