gpt4 book ai didi

R 友好的希腊字符

转载 作者:行者123 更新时间:2023-12-03 22:31:03 24 4
gpt4 key购买 nike

我注意到我可以使用一些希腊字母作为名称,而其他字母则是非法的或只是拉丁字母表中字母的别名。

基本上我可以用 βµ (虽然 β 在打印时更改为 ß 并且 ßβ 充当别名)

list(β = 1)
# $ß
# [1] 1
list(μ = 1)
# $µ
# [1] 1

α、Γ、δ、ε、Θ、π、Σ、σ、τ、Φ、φ 和 Ω 是允许的,但用作拉丁字母的别名。
list(α = 1)
# $a
# [1] 1

αa <- 42
aa
# [1] 42

GG <- 33
ΓΓ
# [1] 33

我测试过的其他字母不“工作”:
ι <- 1
# Error: unexpected input in "\"
Λ <- 1
# Error: unexpected input in "\"
λ <- 1
#Error: unexpected input in "\"

我很惊讶 λ因为它由包 wrapr 定义的 define_lambda ,所以我认为这取决于系统。

我知道相似或相同的字符可以有不同的编码,其中一些不适合在应用程序之间复制/粘贴,这个问题的代码在粘贴回 RStudio 时返回描述的输出。

?make.names 说:

A syntactically valid name consists of letters, numbers and the dot or underline characters and starts with a letter or the dot not followed by a number



所以问题的一部分是:什么是字母?这是怎么回事?

进一步来说:
  • 是否有希腊字符可以安全地用于所有 R 安装,特别是 µβ (或 ß )可以安全地在包中使用。
  • 为什么不是 λ ( intToUtf8(955) ) 可以在我的系统上使用,而它似乎通常被 wrapr 使用的用户。
  • 是否还有其他非拉丁字母(希腊语或非拉丁语)可以在我的代码中安全使用? (例如挪威语 ø 看起来很酷,似乎可以在我的系统上运行)

  • 这一切都是因为我正在寻找一个(或 2 个)字符的函数名称,它不会与现有或常用的名称冲突,并且看起来有点时髦。 .已经用了很多,我用 .. 也已经。

    来自 sessionInfo() :
    R version 3.5.2 (2018-12-20)
    Platform: x86_64-w64-mingw32/x64 (64-bit)
    Running under: Windows >= 8 x64 (build 9200)

    Matrix products: default

    locale:
    [1] LC_COLLATE=English_United Kingdom.1252 LC_CTYPE=English_United Kingdom.1252 LC_MONETARY=English_United Kingdom.1252
    [4] LC_NUMERIC=C LC_TIME=English_United Kingdom.1252

    最佳答案

    我无论如何都不是专家,但让我们尝试分析问题。最后,编译器需要理解您的 R 代码,因此 make.names() 的源代码可能会有所帮助:

    names <- as.character(names)
    names2 <- .Internal(make.names(names, allow_))
    if (unique) {
    o <- order(names != names2)
    names2[o] <- make.unique(names2[o])
    }
    names2

    现在, .Internal() 调用 R 解释器(用 C 编写),所以我们需要更深入一些。负责处理 make.names() 请求的 C 代码可以在这里找到: https://github.com/wch/r-source/blob/0dccb93e114b00b2fcbe75e8721f11a8f2ffdff4/src/main/character.c

    一个简短的剪辑:
    SEXP attribute_hidden do_makenames(SEXP call, SEXP op, SEXP args, SEXP env)
    {
    SEXP arg, ans;
    R_xlen_t i, n;
    int l, allow_;
    char *p, *tmp = NULL, *cbuf;
    const char *This;
    Rboolean need_prefix;
    const void *vmax;

    checkArity(op ,args);
    arg = CAR(args);
    if (!isString(arg))
    error(_("non-character names"));
    n = XLENGTH(arg);
    allow_ = asLogical(CADR(args));
    if (allow_ == NA_LOGICAL)
    error(_("invalid '%s' value"), "allow_");
    PROTECT(ans = allocVector(STRSXP, n));
    vmax = vmaxget();
    for (i = 0 ; i < n ; i++) {
    This = translateChar(STRING_ELT(arg, i));
    l = (int) strlen(This);
    /* need to prefix names not beginning with alpha or ., as
    well as . followed by a number */
    need_prefix = FALSE;
    if (mbcslocale && This[0]) {
    int nc = l, used;
    wchar_t wc;
    mbstate_t mb_st;
    const char *pp = This;
    mbs_init(&mb_st);
    used = (int) Mbrtowc(&wc, pp, MB_CUR_MAX, &mb_st);
    pp += used; nc -= used;
    if (wc == L'.') {
    if (nc > 0) {
    Mbrtowc(&wc, pp, MB_CUR_MAX, &mb_st);
    if (iswdigit(wc)) need_prefix = TRUE;
    }
    } else if (!iswalpha(wc)) need_prefix = TRUE;
    } else {
    if (This[0] == '.') {
    if (l >= 1 && isdigit(0xff & (int) This[1])) need_prefix = TRUE;
    } else if (!isalpha(0xff & (int) This[0])) need_prefix = TRUE;
    }
    if (need_prefix) {
    tmp = Calloc(l+2, char);
    strcpy(tmp, "X");
    strcat(tmp, translateChar(STRING_ELT(arg, i)));
    } else {
    tmp = Calloc(l+1, char);
    strcpy(tmp, translateChar(STRING_ELT(arg, i)));
    }
    if (mbcslocale) {
    /* This cannot lengthen the string, so safe to overwrite it. */
    int nc = (int) mbstowcs(NULL, tmp, 0);
    if (nc >= 0) {
    wchar_t *wstr = Calloc(nc+1, wchar_t);
    mbstowcs(wstr, tmp, nc+1);
    for (wchar_t * wc = wstr; *wc; wc++) {
    if (*wc == L'.' || (allow_ && *wc == L'_'))
    /* leave alone */;
    else if (!iswalnum((int)*wc)) *wc = L'.';
    }
    wcstombs(tmp, wstr, strlen(tmp)+1);
    Free(wstr);
    } else error(_("invalid multibyte string %d"), i+1);
    } else {
    for (p = tmp; *p; p++) {
    if (*p == '.' || (allow_ && *p == '_')) /* leave alone */;
    else if (!isalnum(0xff & (int)*p)) *p = '.';
    /* else leave alone */
    }
    }
    // l = (int) strlen(tmp); /* needed? */
    SET_STRING_ELT(ans, i, mkChar(tmp));
    /* do we have a reserved word? If so the name is invalid */
    if (!isValidName(tmp)) {
    /* FIXME: could use R_Realloc instead */
    cbuf = CallocCharBuf(strlen(tmp) + 1);
    strcpy(cbuf, tmp);
    strcat(cbuf, ".");
    SET_STRING_ELT(ans, i, mkChar(cbuf));
    Free(cbuf);
    }
    Free(tmp);
    vmaxset(vmax);
    }
    UNPROTECT(1);
    return ans;
    }

    正如我们所见,使用了依赖于编译器的数据类型,例如 wchar_t ( http://icu-project.org/docs/papers/unicode_wchar_t.html )。这意味着 make.names() 的行为取决于用于编译 R 解释器本身的 C 编译器。问题是 C 编译器不是很标准化,因此无法对字符的行为进行假设。包括操作系统、硬件、语言环境等在内的一切都可以改变这种行为。

    总之,如果您想保存,我会坚持使用 ASCII 字符,尤其是在不同操作系统之间共享代码时。

    关于R 友好的希腊字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55531887/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com