#c #c #r
#c #c #r
Вопрос:
Позвольте мне объяснить, что делает функция ‘which’:
Из справки GNU-R:
какие индексы являются ИСТИННЫМИ?
Укажите ‘ИСТИННЫЕ’ индексы логического объекта с учетом индексов массива.
или показ некоторого кода: (GNU-R начинает подсчет индексов с 1)
> x <- c(1,2,3,1,3,5);
> which(x == 1);
[1] 1 4
> which(x == 3);
[1] 3 5
> ll <- c(TRUE,FALSE,TRUE,NA,FALSE,FALSE,TRUE);
> which(ll);
[1] 1 3 7
Кто-нибудь знает подобную функцию в C / C ?
Спасибо за вашу помощь
rinni
Комментарии:
1.
std::find_if
илиstd::copy_if
в зависимости от того, что вы хотите с этим сделать. (Или любой из нескольких других вызовов библиотеки)
Ответ №1:
Вы должны понимать, что R является векторизованным, тогда как C в первую очередь работает с отдельными атомарными фрагментами данных: одним int
, double
, …
С помощью C вы можете изучить алгоритмы STL, с помощью которых вы подходите к этому.
Наконец, на пересечении R и C наш пакет Rcpp содержит некоторые векторизованные операции на C , которые имитируют некоторые операции; подробнее смотрите виньетку Rcpp-sugar в формате pdf (и / или некоторые из наших выступлений по Rcpp).
Комментарии:
1. вы абсолютно правы. Мой первый подход был полностью R-центрирован. Думаю, я должен попробовать это с точки зрения C .
Ответ №2:
Создайте объект-функтор, который вы можете инициализировать значением соответствия, и выполните итерацию по вашему списку с помощью std::for_each
. Так, например:
vector<int> values;
//fill your vector with values;
struct match_functor
{
vector<int> value_array;
int match_value;
match_functor(int value): match_value(value) {}
void operator() (int input_value)
{
if(match_value == input_value)
value_array.push_back(input_value);
}
};
match_functor matches(1);
std::for_each(values.begin(), values.end(), matches);
Теперь к вашему массиву результирующих значений можно получить доступ с помощью matches.value_array[INDEX]
.
В качестве альтернативы, если вы просто хотите иметь обозначения исходного вектора, а не фактические значения, тогда вы можете сделать что-то подобное для вашего объекта functor:
struct match_functor
{
vector<int> index_array;
int match_value;
int index;
match_functor(int value): match_value(value), index(0) {}
void operator() (int input_value)
{
if(match_value == input_value)
index_array.push_back(index);
index ;
}
};
match_functor matches(1);
matches = std::for_each(values.begin(), values.end(), matches);
Теперь matches.index_array[INDEX]
будут храниться индексы исходного вектора, которые соответствуют значению 1
, а не фактические значения из исходного вектора.
Комментарии:
1. ваш первый фрагмент кода — это просто более сложная замена
std::remove_copy_if
.2. Однако это не удаляет никаких значений… она копирует желаемое значение N раз для количества вхождений в исходный вектор.
3. @Jason Да, она копирует значения из входного вектора в какой-либо другой, тем самым удаляя (не копируя) любые значения, которые не соответствуют какому-либо предикату. Это то, что
std::remove_copy_if
делает.4. @Christian Rau: Да, ты прав … извините, я думал о
std::remove_if
том, что изменяет значения в итерируемом контейнере / массиве5. Спасибо за ваши фрагменты, они мне очень помогли. Но, как сказал Дирк, нужно снять свои R-очки и надеть C -очки. Сейчас я придерживаюсь совершенно другого подхода.
Ответ №3:
алгоритм std::find_if
должен выполнить трюк — в сочетании с циклом, который я должен добавить.