简体   繁体   English

Rscript-Knitr:Substr函数在Knitr代码块内无法正常工作

[英]Rscript - knitr: substr function not working correctly inside knitr code chunk

The following code does not work correctly inside knitr code chunk (it does not extract the desired substring): 以下代码在knitr代码块内无法正常工作(它不会提取所需的子字符串):

What might be causing this behavior? 是什么导致此行为?

#Retrieve the earliest date
 earlydate <- min(time(month[1]), "2016-04-20")

 earlydate

 #Extract YYYY-MM from earliest date
 substr(earlydate, 1, 7)

where month[1] is 月份[1]在哪里

            TSLA.Open TSLA.High TSLA.Low TSLA.Close TSLA.Volume TSLA.Adjusted
  2016-02-16     158.7    162.95   154.11     155.17     5556300   155.17

#extracts the date:
time( month[1] ) 

   2016-02-16

Expect to see the following in knitr output (R Markdown): 希望在针织输出中看到以下内容(R Markdown):

## [1] 2016-02

Instead actual output is not extracted, just show original text: 而是不提取实际输出,仅显示原始文本:

## [1] 2016-02-16

However either of the following does works correctly (extracts YYYY-MM): 但是,以下任何一项都可以正常工作(提取YYYY-MM):

#inline r code
`r substr("2016-02-16", 1,7)`

outputs: ## [1] 2016-04 输出: ## [1] 2016-04

#knitr code chunk
```{r test, message=FALSE, warning=FALSE}

earlydate <- "2016-02-16"

earlydate

 #Extract YYYY-MM from earliest date
 substr(earlydate, 1, 7)

```

outputs: ## [1] 2016-04 输出: ## [1] 2016-04

Class Details When both are arguments are type Date 类的详细信息当两个都是参数时,类型为Date

#Retrieve the earliest date
 earlydate <- min(time(month[1]), as.Date("2016-04-20"))

 class(earlydate)
 ## [1] "Date"

When one is type date and the other type "character" 当一个是日期类型而另一个是“字符”类型时

#Retrieve the earliest date
 earlydate <- min(time(month[1]), "2016-04-20")

 class(earlydate)
 ## [1] "Date"

Additional Info 附加信息

Environment 环境

OS: Win7

RStudio Version 0.99.892

Rx64 3.2.4 (R version)

document type: shiny knitr doc (.Rmd)

Library: quantmod

Library: knitr

The substr function does not appear to extract the substring in a shiny knitr Rmd document. substr函数似乎无法提取闪亮的Rmd文档中的子字符串。

Details are in the following stackflow link: 详细信息在以下堆栈流链接中:

Rscript - knitr: substr function not working correctly inside knitr code chunk Rscript-Knitr:Substr函数在Knitr代码块内无法正常工作

Minimal Reproducible Example (this does not extract desired substring): 最小可复制示例 (此示例未提取所需的子字符串):

substr( min( as.Date(2013-03-14), "2016-04-20"), 1,7)
outputs: ## [1] "2013-03-14"

Expect (this works as expected): 预期 (按预期工作):

substr( min( as.Date(2013-03-14), as.Date("2016-04-20")), 1,7)
 outputs (desired): ## [1] "2013-03"

It appears unrelated to knitr, since this behavior is also seen on the R console. 它似乎与knitr无关,因为在R控制台上也可以看到此行为。 Returned classes (as stated above) and data processing do not appear to correlate. 返回的类(如上所述)和数据处理似乎不相关。 It would appear to be an underlying R issue . 这似乎是潜在的R问题

Is this WAD? 这是WAD吗?

BR/KK BR / KK

First, to show what a minimal self-contained reproducible example means, this is all you need to demonstrate the problem: 首先,为了展示一个最小的独立可重现示例的含义,这就是证明问题的全部:

x1 = as.Date('2013-03-14')
x2 = min(x1, '2016-04-20')
substr(x1, 1, 7)  # "2013-03"
substr(x2, 1, 7)  # "2013-03-14"

To investigate the issue, take a look at what these objects really are: 要调查此问题,请看一下这些对象实际上是什么:

dput(x1, '')  # structure(15778, class = "Date")
dput(x2, '')  # structure("15778", class = "Date")

x2 is essentially a character string "15778" masked by a class Date . x2本质上是由Date类掩盖的字符串"15778" What does that mean? 这意味着什么? I do not know (dates are often represented as integers internally instead of characters). 我不知道(日期通常在内部表示为整数而不是字符)。 It is just a weird object returned by min() , when you asked for the minimum of a date and a character string (I do not know what that means, but R returns something anyway). 当您要求输入日期和字符串的最小值时,这只是min()返回的一个奇怪的对象(我不知道这是什么意思,但是R仍然会返回一些内容)。

Why can this object be problematic? 为什么这个对象有问题? Take a look at the source code of substr() : 看一下substr()的源代码:

> substr
function (x, start, stop) 
{
    if (!is.character(x)) 
        x <- as.character(x)
    .Internal(substr(x, as.integer(start), as.integer(stop)))
}

is.character(x2) is TRUE , so it is not coerced to character, then it is passed to an internal function (presumably further passed to a certain C function), and I'm not going to dig deeper, since the lesson should be clear now: do not compare apples with oranges. is.character(x2)TRUE ,因此它不被强制转换为字符,然后将其传递给一个内部函数(大概进一步传递给某个C函数),并且由于该课应现在要清楚:不要将苹果与桔子相提并论。 For example, if you want the minimum of two dates, make sure both values are really dates: 例如,如果要最少两个日期,请确保两个值都是真实日期:

x2 = min(x1, as.Date('2016-04-20'))

Another possibility is to coerce data to a certain type explicitly, eg in this case, you want to do substr() on a character string, so make sure it is indeed character: 另一种可能性是将数据显式强制转换为某种类型,例如,在这种情况下,您要对字符串执行substr() ,因此请确保它确实是字符:

substr(as.character(x2), 1, 7)

Either way solves your original issue, but the first way is recommended. 两种方法都可以解决您的原始问题,但建议采用第一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM