当我尝试"解码"原始或内部R函数时,Ben Bolkers对这个问题的回答和Uwe Ligges的文章已经非常有用.但原始R函数如何与其相应的C函数相连?我想不知何故.Primitive必须提供这个缺失的链接.举个例子is.na:
> is.na
function (x) .Primitive("is.na")
Run Code Online (Sandbox Code Playgroud)
FUNTAB R_FunTab[] 在文件"names.c"中包含
{"is.na", do_isna, 0, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
Run Code Online (Sandbox Code Playgroud)
这意味着is.na使用C函数do_isna.
do_isna在文件"coerce.c"中定义:
SEXP attribute_hidden do_isna(SEXP call, SEXP op, SEXP args, SEXP rho)
{
SEXP ans, dims, names, x;
R_xlen_t i, n;
checkArity(op, args);
check1arg(args, call, "x");
if (DispatchOrEval(call, op, "is.na", args, rho, &ans, 1, 1))
return(ans);
PROTECT(args = ans);
#ifdef stringent_is
if (!isList(CAR(args)) && !isVector(CAR(args)))
errorcall_return(call, …Run Code Online (Sandbox Code Playgroud) 首先,这个问题有一个类似的标题,但环境似乎只是不洁净.到现在为止,我想到了
rm(list=ls(globalenv()))
Run Code Online (Sandbox Code Playgroud)
我们的全球环境与R首次启动时一样干净.但偶然我意识到至少类定义存活下来:
rm(list=ls(globalenv()),envir=globalenv())
sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})
ls(globalenv())
getClasses(globalenv())
#----------------------------------------------------------------
x <- 1:3
setClass("A", where=globalenv())
ls(globalenv())
getClasses(globalenv())
#----------------------------------------------------------------
rm(list=ls(globalenv()),envir=globalenv())
ls(globalenv())
getClasses(globalenv())
#----------------------------------------------------------------
sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})
ls(globalenv())
getClasses(globalenv())
Run Code Online (Sandbox Code Playgroud)
警告:运行此可重现示例后,您的全局环境将比"rm(list = ls())"之后更清晰.
> source('~/.active-rstudio-document', echo=TRUE)
> rm(list=ls(globalenv()),envir=globalenv())
> sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})
named list()
> ls(globalenv())
character(0)
> getClasses(globalenv())
character(0)
> #----------------------------------------------------------------
> x <- 1:3
> setClass("A", where=globalenv())
> ls(globalenv())
[1] "x"
> getClasses(globalenv())
[1] "A"
> #----------------------------------------------------------------
> rm(list=ls(globalenv()),envir=globalenv())
> ls(globalenv())
character(0)
> getClasses(globalenv())
[1] "A"
> #----------------------------------------------------------------
> sapply(getClasses(globalenv()),function(x){removeClass(x,where=globalenv())})
A
TRUE
> …Run Code Online (Sandbox Code Playgroud) 通过类POSIXlt的文档,类POSIXlt的对象是一个命名列表.事实上:
> tm <- strptime( "24-12-2015 05:28:12", format="%d-%m-%Y %H:%M:%S", tz="UTC" )
> class(tm)
[1] "POSIXlt" "POSIXt"
> tm$sec
[1] 12
> tm$min
[1] 28
> tm$hour
[1] 5
> tm$mday
[1] 24
> tm$mon
[1] 11
> tm$year
[1] 115
> tm$wday
[1] 4
> tm$yday
[1] 357
> tm$isdat
NULL
> tm$zone
NULL
> tm$gmtoff
NULL
Run Code Online (Sandbox Code Playgroud)
类列表的文档说,is.list(tm)当且仅当tm列表或者是一个pairlist时,它is.pairlist(tm)是TRUE ,并且当且仅当它tm是一个pairlist或NULL 时才为TRUE .
> is.list(tm)
[1] TRUE …Run Code Online (Sandbox Code Playgroud) 有时print需要两次尝试打印data.table:
> library(data.table)
>
> rm(list=ls())
>
> Tbl <- fread( input = "Nr; Value
+ Nr 1;46.73
+ Nr 2;49.02
+ Nr 3;50.62
+ Nr 4;49.80
+ Nr 5;50.15",
+ sep = ";",
+ header = TRUE,
+ colClasses = c("character","numeric") )
> print(Tbl)
Nr Value
1: Nr 1 46.73
2: Nr 2 49.02
3: Nr 3 50.62
4: Nr 4 49.80
5: Nr 5 50.15
> Tbl <- Tbl[, Nr := as.numeric( gsub( "Nr …Run Code Online (Sandbox Code Playgroud) 在类"ECDF"从类"stepfun"继承.如果f是这样的经验累积密度函数,都is.stepfun(f)和is(f,"stepfun")都TRUE和as.stepfun(f)预期没有做任何事情.但是由于"元数据",转换f为"stepfun" as(f,"stepfun")是不可能的,即使strict是FALSE:
f <- ecdf(1:10)
class(f)
# [1] "ecdf" "stepfun" "function"
is.stepfun(f)
# [1] TRUE
is(f,"stepfun")
# [1] TRUE
identical(f,as.stepfun(f))
# [1] TRUE
g <- as(f,"stepfun",strict=FALSE)
# Error in as(f, "stepfun", strict = FALSE) :
# internal problem in as(): “ecdf” is(object, "stepfun") is TRUE, but the metadata asserts that the 'is' relation is FALSE
Run Code Online (Sandbox Code Playgroud)
那么这里的"元数据"是如何is相关的as呢?