Правильная структура в R зависит от того, как выглядит ваш struct
. Именованный список является самым общим. Здесь простая реализация примера для функции wrap
, упомянутой в комментариях:
#include <RcppCommon.h>
typedef struct {
char* firstname[128];
char* lastname[128];
int nbrOfSamples;
} HEADER_INFO;
namespace Rcpp {
template <>
SEXP wrap(const HEADER_INFO& x);
}
#include <Rcpp.h>
namespace Rcpp {
template <>
SEXP wrap(const HEADER_INFO& x) {
Rcpp::CharacterVector firstname(x.firstname, x.firstname + x.nbrOfSamples);
Rcpp::CharacterVector lastname(x.lastname, x.lastname + x.nbrOfSamples);
return Rcpp::wrap(Rcpp::List::create(Rcpp::Named("firstname") = firstname,
Rcpp::Named("lastname") = lastname,
Rcpp::Named("nbrOfSamples") = Rcpp::wrap(x.nbrOfSamples)));
};
}
// [[Rcpp::export]]
HEADER_INFO getHeaderInfo() {
HEADER_INFO header;
header.firstname[0] = (char*)"Albert";
header.lastname[0] = (char*)"Einstein";
header.firstname[1] = (char*)"Niels";
header.lastname[1] = (char*)"Bohr";
header.firstname[2] = (char*)"Werner";
header.lastname[2] = (char*)"Heisenberg";
header.nbrOfSamples = 3;
return header;
}
/*** R
getHeaderInfo()
*/
Выход:
> getHeaderInfo()
$firstname
[1] "Albert" "Niels" "Werner"
$lastname
[1] "Einstein" "Bohr" "Heisenberg"
$nbrOfSamples
[1] 3
Однако для этого частного случая a data.frame
было бы более естественно использовать, что может быть достигнуто путем замены выше wrap
на:
template <>
SEXP wrap(const HEADER_INFO& x) {
Rcpp::CharacterVector firstname(x.firstname, x.firstname + x.nbrOfSamples);
Rcpp::CharacterVector lastname(x.lastname, x.lastname + x.nbrOfSamples);
return Rcpp::wrap(Rcpp::DataFrame::create(Rcpp::Named("firstname") = firstname,
Rcpp::Named("lastname") = lastname));
};
Выход:
> getHeaderInfo()
firstname lastname
1 Albert Einstein
2 Niels Bohr
3 Werner Heisenberg
R обрабатывает обратную косую черту как escape-значения для символьных констант . (... и, следовательно, регулярные выражения. Следовательно, необходимо наличие двух обратных косых черт при поставке символьного аргумента для шаблона. Первый - это не символ, а второй - символ). Вы можете видеть как они обрабатываются с помощью cat
.
y <- "double quote: \", tab: \t, newline: \n, unicode point: \u20AC"
print(y)
## [1] "double quote: \", tab: \t, newline: \n, unicode point: €"
cat(y)
## double quote: ", tab: , newline:
## , unicode point: €
Дальнейшее чтение: Выключение обратной косой черты с обратным слэшем в R вызывает 2 обратных слэша в строке, а не 1
Чтобы использовать специальные символы в регулярном выражении, простейший метод обычно избегает их с обратным слэшем, но, как отмечалось выше, обратная косая черта должна быть экранирована.
grepl("\\[", "a[b")
## [1] TRUE
Чтобы совместить обратную косую черту, вам нужно удвоить бегство, в результате получится четыре обратных косые черты.
grepl("\\\\", c("a\\b", "a\nb"))
## [1] TRUE FALSE
Пакет rebus
содержит константы для каждого из специальных символов, чтобы сэкономить вам чернильные черты.
library(rebus)
OPEN_BRACKET
## [1] "\\["
BACKSLASH
## [1] "\\\\"
Дополнительные примеры см. в:
?SpecialCharacters
. Ваша проблема может быть решена следующим образом:
library(rebus)
grepl(OPEN_BRACKET, "a[b")
Вы также можете обернуть специальные символы в квадрате b ракеты для формирования класса символов .
grepl("[?]", "a?b")
## [1] TRUE
Два специальных символа имеют особое значение внутри классов символов: \
и ^
.
Обратная косая черта должен быть экранирован, даже если он находится внутри класса символов.
grepl("[\\\\]", c("a\\b", "a\nb"))
## [1] TRUE FALSE
Резерв должен быть только экранирован, если он находится непосредственно после квадратной скобки открытия.
grepl("[ ^]", "a^b") # matches spaces as well.
## [1] TRUE
grepl("[\\^]", "a^b")
## [1] TRUE
rebus
также позволяет вам сформировать класс символов.
char_class("?")
## <regex> [?]
Если вы хотите совместить все знаки препинания, вы можете использовать символ [:punct:]
class.
grepl("[[:punct:]]", c("//", "[", "(", "{", "?", "^", "$"))
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
stringi
сопоставляет это с общей категорией Unicode для пунктуации, поэтому его поведение немного отличается.
stri_detect_regex(c("//", "[", "(", "{", "?", "^", "$"), "[[:punct:]]")
## [1] TRUE TRUE TRUE TRUE TRUE FALSE FALSE
Вы также можете использовать кросс-платформенную синтаксис для доступа к UGC.
stri_detect_regex(c("//", "[", "(", "{", "?", "^", "$"), "\\p{P}")
## [1] TRUE TRUE TRUE TRUE TRUE FALSE FALSE
Размещение символов между \\Q
и \\E
делает механизм регулярного выражения обрабатывать их буквально, а не как регулярные выражения.
grepl("\\Q.\\E", "a.b")
## [1] TRUE
rebus
позволяет писать литеральные блоки регулярных выражений.
literal(".")
## <regex> \Q.\E
Регулярные выражения не всегда являются ответом. Если вы хотите сопоставить фиксированную строку, вы можете сделать это, например:
grepl("[", "a[b", fixed = TRUE)
stringr::str_detect("a[b", fixed("["))
stringi::stri_detect_fixed("a[b", "[")
Я думаю, что самый простой способ сопоставления символов, таких как
\^$.?*|+()[
, использует классы символов изнутри R. Рассмотрим, как очистить заголовки столбцов от файла данных, которые могут содержать пробелы и пунктуацию characters:
> library(stringr)
> colnames(order_table) <- str_replace_all(colnames(order_table),"[:punct:]|[:space:]","")
Этот подход позволяет нам вводить классы символов в соответствие с символами пунктуации, в дополнение к символам пробелов, что вам обычно нужно было бы избежать с помощью \\
для обнаружения. Вы можете узнать больше о классах символов в этой таблице ниже, и вы также можете ввести ?regexp
, чтобы узнать больше об этом.
https://www.rstudio.com/wp -поперечник / добавления / 2016/09 / RegExCheatsheet.pdf