Проблема с R и вектором NA добавлены значения - PullRequest
0 голосов
/ 24 сентября 2018

Я просмотрел это и не могу понять, почему это дает мне значения NA, добавленные к нужному мне вектору.Подсказка ниже:

"Функция должна возвращать вектор, где первый элемент является суммой первых n элементов входного вектора, а оставшаяся часть вектора является копией других элементоввектор ввода. Например, если вектор ввода (2, 3, 6, 7, 8) и n = 2, то на выходе должен быть вектор (5, 6, 7, 8) "

 testA<- c(1,2,3,4,5)    
myFunction <- function(vector1, n)
       {
       sum1=0
       for(i in 1:n)
         {
          sum1<-sum1+vector1[i]
          newVector<-c(sum1,vector1[n+1:length(vector1)])
         }
       return(newVector)
         }

print(newVector) 
myFunction(testA, 3)

Выход: [1] 6 4 5 NA NA NA, когда он должен быть просто6 4 5

Ответы [ 5 ]

0 голосов
/ 25 сентября 2018

Уже есть отличные решения, но есть еще один вариант, который вносит минимальные изменения в ваш оригинальный код:

testA<- c(1,2,3,4,5)    
myFunction <- function(vector1, n)
{
  sum1=0
  for(i in 1:n)
  {
    sum1<-sum1+vector1[i]
  }

  newVector<-c(sum1,vector1[(n+1):length(vector1)]) # we take this line out of the for loop
  # and put the n+1 in between parenthesis

  return(newVector)
}
newVector <- myFunction(testA, 3)
print(newVector) 

Проблема в исходном коде / примере заключалась в том, что n+1:length(vector1) было возвращено [1] 4 5, чтобы выполнить соответствующее поднабор (получение последних элементов в векторе, которые не были включены в сумму первых n элементов), но фактически возвращает [1] 4 5 6 7 8.Поскольку в позициях 6:8 в testA нет элементов, это является причиной появления пропущенных значений / NA.

На самом деле n+1:length(vector1) вначале получает последовательность 1:length(vector1) изатем добавив n к каждому элементу.Вот пример такого поведения с использованием значений:

3+1:5
#> [1] 4 5 6 7 8

Мы можем решить эту проблему, поставив n+1 в скобках исходного кода.В нашем примере с использованием значений:

(3+1):5
#> [1] 4 5

Кроме того, удаление назначения newVector из цикла повышает производительность, поскольку связывание между sum1 и подмножественным вектором необходимо выполнять только после суммирования.из первых n элементов завершено.

0 голосов
/ 24 сентября 2018

Спасибо за ответы всех!Я очень устал прошлой ночью и не смог придумать такое простое решение:

    function(vector1, n)
  {
  sum1=0
  for(i in 1:n) #scans input vector from first element to input 'n' element
    {
    sum1<-sum1+vector1[i]#Find sum of numbers scanned 
    newVector<-c(sum1,vector1[n+1:length(vector1)])#new output vector starting with the sum found then concatonates rest of the original vector after 'n' element
    length(newVector)<-(length(newVector)-(n)) #NA values were returned, length needs to be changed with respect to 'n'
  }
  return(newVector)
  print(newVector)
}
0 голосов
/ 24 сентября 2018

Это может быть сделано с head и tail

n <- 2
c(sum(head(test, 2)), tail(test, -2))
#[1] 5 6 7 8

data

test <- c(2, 3, 6, 7, 8)
0 голосов
/ 24 сентября 2018

Здесь я пытаюсь сравнить эффективность двух вышеупомянутых функций, которые являются ответом на пост https://stackoverflow.com/a/52472214/3806250 с вопросом на пост.

> testA <- 1:5    
> myFunction <- function(vector1, n) {
+        sum1 <- 0
+        for(i in 1:n) {
+           sum1 <- sum1 + vector1[i]
+           newVector <- c(sum1, vector1[n+1:length(vector1)])
+          }
+        newVector <- newVector[!is.na(newVector)]
+        return(newVector)
+        }
> 
> microbenchmark::microbenchmark(myFunction(testA, 3))
Unit: microseconds
                 expr   min     lq     mean median    uq     max neval
 myFunction(testA, 3) 3.592 4.1055 77.37798  4.106 4.619 7292.85   100
> 
> myfunction <- function(x, n) c(sum(x[1:n]), x[-(1:n)])
> 
> microbenchmark::microbenchmark(myfunction(testA, 2))
Unit: microseconds
                 expr   min   lq     mean median    uq      max neval
 myfunction(testA, 2) 1.539 1.54 47.04373  2.053 2.053 4462.644   100
0 голосов
/ 24 сентября 2018

Здесь нет необходимости в цикле for; вы можете сделать что-то подобное

test <- c(2, 3, 6, 7, 8)

myfunction <- function(x, n) c(sum(x[1:n]), x[-(1:n)])
myfunction(test, 2)
#[1] 5 6 7 8

testA <- c(1,2,3,4,5)   
myfunction(testA, 3)
#[1] 6 4 5

Объяснение: sum(x[1:n]) вычисляет сумму первого nэлементы x и x[-(1:n)] возвращают x с удалением первых n элементов.

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