Существует ли эквивалентная функция в C / C для GNU-R which()?

#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 должен выполнить трюк — в сочетании с циклом, который я должен добавить.