2015-02-04 4 views
2

Несомненно, вопрос facepalm, извините. Я пытался RTFM и google, но не повезло.Функция R с циклом FOR на векторе

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

func1 <- function(vector) { 
    vr <- c() ### an empty vector 

    for (i in 1:length(vector)) { 
    vr <- vector[i]+i 
    } 
} 

Для меня это выглядит правильно, но я всегда получаю вектор NULL. Зачем?

+0

Вы можете просто падение 'Vr <- с()' и 'Vr <- вектор [I] + i' и положить' вектор [я] < - вектор [i] + 1' в цикле 'for'. И не забудьте вернуть объект в конце функции ('return (vector)' или просто 'vector'). – nrussell

+2

Не '' функция (v) {v + 1: length (v)} 'достаточно? Вы переписываете 'vr' в каждом цикле. – tonytonov

ответ

5

Вы могли бы написать, что гораздо более эффективно, как это:

func1 <- function(vector){ 
    vector + seq_along(vector) 
} 

Таким образом, вы принимаете преимущество сложения векторов.

Для полноты рассмотрим эти два решения. Вот общее решение цикла:

func2 <- function(vector) { 
    vr <- c() ### an empty vector 

    for (i in 1:length(vector)) { 
     vr[i] <- vector[i]+i 
    } 
    vr 
} 

Как шаг вверх, есть также решение на месте

func3 <- function(vector) {  
    for (i in 1:length(vector)) { 
     vector[i] <- vector[i]+i 
    } 
    vector 
} 

Использование microbenchmark мы можем видеть, что векторизация решение на сегодняшний день является наиболее эффективным.

vec <- sample(100000, 10000) 

library(microbenchmark) 
microbenchmark(func1(vec), func3(vec), func2(vec)) 

Unit: microseconds 
     expr  min  lq   mean median  uq   max neval cld 
func1(vec) 29.998 36.984  44.78312 42.736 44.38  399.006 100 a 
func3(vec) 12845.823 13666.432 14452.02863 14060.712 14708.53 25025.950 100 a 
func2(vec) 84898.055 87354.750 110046.26659 88634.566 91193.38 1042819.269 100 b 
+0

ОК, я вижу. Это было действительно: facepalm ": Я предположил, что он просто сбрасывает полный вектор в vr ... да, это очень глупое предположение. Я занимался часами, LOL. И большое спасибо за seq_along функция и эталонная библиотека очень полезны! – runlevel0

2

Ваш код завершен, но имеет две проблемы. Во-первых, если не указано с вызовом return(), функции в R возвращают последнее выражение. В вашей функции это сам цикл for. Но выражение for loop ничего не возвращает и само по себе.

Во-вторых, последняя строка не индексируется на vr, поэтому вы полностью переписываете ее с последним результатом в цикле.

Таким образом, этот код будет (я думаю) делать то, что вы хотите. Но согласился с другим ответом, что есть более простые способы сделать это.

func1 <- function(vector) { 
    vr <- c() ### an empty vector 

    for (i in 1:length(vector)) { 
    vr[i] <- vector[i]+i 
    } 
    vr 
} 

Это дает этот результат:

> func1(c(1,2)) 
[1] 2 4 
+1

Хороший ответ. Тем не менее, это не то, как вы обычно пишете это в Р. –