Разница между символами и персонажами

Из определения языка:

"char": скалярный строковый объект (только для внутреннего использования) ***
"персонаж": вектор, содержащий символьные значения

Пользователи не могут легко завладеть объектами типов, помеченных ‘***.

y <- "My name is hasnain"
class(y)

Функции класса говорят, что y принадлежит классу символов. Я понял, что "у" - это объект типа char, который принадлежит классу символов. Объект персонажа также принадлежит к классу персонажей?

Ответы

Ответ 1

Два типа R char и character на внутренней стороне C соответствуют CHARSXP и STRSXP соответственно. На уровне R каждый всегда имеет дело с объектами character; одна строка, например:

y <- "My name is hasnain"

на самом деле является объектом character длиной 1. Внутренне каждый элемент character является char, но R не предоставляет (AFAIK) прямой способ извлечения, создания и/или использования char.

Хотя вы не можете создать объект char/CHARSXP с чистым R, просто получить его через интерфейс R/C с помощью функции mkChar, которая берет стандартную строку C и превращает ее в CHARSXP. Например, можно создать файл char.c:

#include <stdio.h>
#include <stdlib.h>
#include <R.h>
#include <Rinternals.h>
SEXP returnCHAR() {
   SEXP ret = PROTECT(mkChar("Hello World!"));
   UNPROTECT(1);
   return ret;
}

После компиляции через R CMD SHLIB char.c со стороны R:

dyn.load("char.so")  #linux dll; extension varies across platforms
x<-.Call("returnCHAR")
x
# <CHARSXP: "Hello World!">
typeof(x)
#[1] "char"
length(x)
#[1] 12

Кроме typeof и length я не нашел много других функций R, которые действуют на объекты char. Даже as.character не работает! Я не мог ни извлечь char из стандартного вектора character, ни вставить этот char в существующий вектор character (назначение не работает).

Функция c приводит к list, если объект является char:

c(1,"a",x)
#[[1]]
#[1] 1
#
#[[2]]
#[1] "a"
#
#[[3]]
#<CHARSXP: "Hello World!">

Мы можем использовать .Internal(inspect()) (предупреждение: inspect - это внутренняя неэкспонированная функция, и поэтому она может измениться в будущих выпусках. Не полагайтесь на нее), чтобы иметь представление о внутренней структуре объект. Насколько я знаю, объекты char/CHARXSP распределяются между строковыми векторами для экономии памяти. Например:

let<-letters[1:2]
.Internal(inspect(let))
#@1aff2a8 16 STRSXP g0c2 [NAM(1)] (len=2, tl=0)
#  @1368c60 09 CHARSXP g0c1 [MARK,gp=0x61] [ASCII] [cached] "a"
#  @16dc7c0 09 CHARSXP g0c1 [MARK,gp=0x60] [ASCII] [cached] "b"
mya<-"a"
.Internal(inspect(mya))
#@3068710 16 STRSXP g0c1 [NAM(3)] (len=1, tl=0)
#  @1368c60 09 CHARSXP g0c1 [MARK,gp=0x61] [ASCII] [cached] "a"

Из приведенного выше вывода отметим две вещи:

  • STRSXP объекты - это векторы объектов CHARSXP, как мы уже упоминали;
  • строки хранятся в "глобальном пуле": строка "a" хранится по одному и тому же адресу, несмотря на то, что она создается независимо в двух разных объектах.

Ответ 2

Согласно никола ответ

Два типа R char и символ на внутренней стороне C соответствуют CHARSXP и STRSXP соответственно. На уровне R каждый всегда имеет дело с объектами персонажа; одна строка, например:

y <- "My name is hasnain"

В R фрагмент текста представлен в виде последовательности символов (букв, цифр и символов). Тип данных R предусматривает для хранения последовательности символов символ. Формально режим объекта, который содержит символьные строки в R, является "символьным".

Символьный объект используется для представления строковых значений в R. Мы преобразуем объекты в символьные значения с помощью функции as.character():

> x = as.character(3.14) 
> x              # print the character string 
[1] "3.14" 
> class(x)       # print the class name of x 
[1] "character"

Символ/строка - каждый элемент вектора представляет собой строку из одного или нескольких символов. Встроенные символьные векторы - это буквы и буквы, которые обеспечивают 26 нижних (и верхних) прописные буквы, соответственно.

> y = c("a", "bc", "def")
> length(y)
[1] 3
> nchar(y)
[1] 1 2 3
> y == "a"
[1] TRUE FALSE FALSE
> y == "b"
[1] FALSE FALSE FALSE

Это так же просто, как и то, что да, вы правильно поняли, что y является объектом типа char, и он принадлежит классу символов/строк, но тогда и только тогда, когда 'a' здесь последовательность символов, образующих строку/символ