【发布时间】:2013-07-25 18:42:25
【问题描述】:
我在此转发my problem,因为我注意到这是 knitr 的作者建议的获得更多帮助的方法。
我对 .Rmd 文件有点困惑,我可以在交互式 R 会话中逐行处理,也可以使用 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 控制台中使用调用按预期工作...
问题与 format 生成 ID 的方式有关(在 ltraj2sldf 的 apply 调用中),就在 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 生成的更多细节。基本上,ID 是通过apply 调用在数据帧的每一行生成的,该调用又使用format,如下所示:format(dfi["id"], scientific = FALSE)。这里,id 列只是一个从 1 到行数 (1:nrow(df)) 的序列。 scientific = FALSE只是为了确保我没有100000的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"
请注意,一次处理一个相同的结果会产生预期的结果:
> 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 一样(正如我对 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
【问题讨论】:
-
long-shot:
knitr可能会更改某些格式选项(例如有效数字的数量),从而以某种方式影响 ID 的生成方式。 -
可能是这样。但我仍然看不到哪些选项会影响此输出。让我在我的第一条消息中添加有关生成 ID 的更多详细信息……看看它是否更有意义!谢谢。
-
你能用这个格式问题做一个最小的例子吗?我不了解有关应用和空白填充的内容。您的列表中有 10000 个吗?
-
诚然,我也不明白! :) 但是,是的,该表大于 100,000 行,因此生成的 ID 也高于此值。我已经尝试提出一个最小的可重现示例,但到目前为止没有成功(由于我不明白的原因,当我过多地减少该示例时问题就消失了)。我会再试一次,然后回到这里。
-
在这种特定情况下,
format()不是一个好的选择,因为结果可能会受到许多全局选项的影响;为了忠实地获得您的数字的字符表示,我建议您简单地使用as.character(),然后不会发生任何花哨的事情。顺便说一句,我很高兴你听从了我的建议来到 SO。如您所见,一位作者(即我)的帮助和响应能力远不如这里的数千名专家:)
标签: r interactive knitr