r - возникают проблемы при применении функции к вектору - PullRequest
0 голосов
/ 06 февраля 2020

Все еще довольно плохо знаком с R, поэтому я не уверен, что делаю неправильно. Я пытаюсь применить эту функцию к вектору для вычисления% остатка на основе начального значения:

residual <- function(vec, offset, lngth){

 denom <- 1
 res_vec <- NULL
 for (i in 1:lngth){    

     if(i == 1 | i %% (offset) != 0)
{
         x <- vec[i] * 100/vec[denom]
         res_vec <- append(res_vec, x)
}

     else
{
         denom <- denom + offset
         x <- vec[i] * 100/vec[denom]
         res_vec <- append(res_vec, x)
}

}

res_vec
}

Я использую sapply. Например, если мой вектор:

dv <- c(88, 84, 80, 90, 88, 85)

И я использую sapply

x <- sapply(dv, residual, offset = 3, lngth = 6)

Я бы хотел получить этот вектор:

100, 95, 91, 100, 98, 94

Но вместо этого Я либо получаю следующее:

         [,1] [,2] [,3] [,4] [,5] [,6]
[1,]  100  100  100  100  100  100
[2,]   NA   NA   NA   NA   NA   NA
[3,]   NA   NA   NA   NA   NA   NA
[4,]   NA   NA   NA   NA   NA   NA
[5,]   NA   NA   NA   NA   NA   NA
[6,]   NA   NA   NA   NA   NA   NA

Что-то не так с моей функцией, или я что-то не так делаю, когда пытаюсь ее вызвать? Я получил это работать нормально в C ++.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 07 февраля 2020

Если я правильно понимаю, ОП хочет разрезать вектор на части по offset элементов каждый и делить элементы каждого элемента на первый элемент каждого элемента. Затем кусочки добавляются снова.

Здесь есть две задачи:

  1. Группировка элементов вектора
  2. Расчет результата для каждой группы

Одним из подходов в базе R является функция ave():

dv <- c(88, 84, 80, 90, 88, 85)
offset <- 3L
ave(dv, cumsum(seq_along(dv) %% offset == 1L), 
    FUN = function(x) round(100 * x / x[1]))

, которая возвращает

[1] 100  95  91 100  98  94

, как и ожидалось.

Выражение

cumsum(seq_along(dv) %% offset == 1L)

делает группировку

[1] 1 1 1 2 2 2

В качестве альтернативы мы можем использовать rep()

rep(seq_along(dv), each = offset, length.out = length(dv))
0 голосов
/ 06 февраля 2020

В этом случае вам не нужно использовать функцию apply. Вы должны иметь возможность просто ввести свой вектор в свою пользовательскую функцию:

residual(vec = dv,  offset = 3, lngth = 6)

Однако, похоже, это не дает желаемого результата, поэтому я думаю, что может быть что-то не так с функцией, которую вы написано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...