LINUX.ORG.RU

Как в R итерироваться по разницам между элементами вектора

 ,


2

6

Собственно сабж.

Хочется чего-то типа:

ivec <- c(1:10)
ovec <- someMysticFunction(ivec, function(x) x)

Пока пораженный императивным погроммированием мозг выдал только

ivec <- c(1:10)
iveclenmo <- length(ivec) - 1
ovec <- sapply(c(1:iveclenmo), function(x) { y <- ivec[x+1] - ivec[x]; y })

★★★★★

Последнее исправление: Stil (всего исправлений: 1)

Как вариант

Prelude> let sample = take 10 $ scanl (+) 0 [1,2..]
Prelude> sample
[0,1,3,6,10,15,21,28,36,45]
Prelude> let mysticFunction = id
Prelude> zipWith (-) (tail sample) sample
[1,2,3,4,5,6,7,8,9]
Prelude> map mysticFunction $ zipWith (-) (tail sample) sample
[1,2,3,4,5,6,7,8,9]

На R сам переведешь :)

yoghurt ★★★★★
()

надо прощее писать :)

sapply(1:(length(ivec)-1), function(x) ivec[x+1] - ivec[x])
или как то так

vmyfun<-Vectorize(myfun)
vmyfun(ivec[-1], ivec[-length(ivec)])

Принудительная векторизация понятно дело необходимое только когда исходная функция не понимает векторные аргументы

psv1967 ★★★★★
()
Последнее исправление: psv1967 (всего исправлений: 2)
Ответ на: комментарий от psv1967

надо прощее писать :)

Вот кстати научи делать слайсы...

Когда надо порезать data.frame с заведомо известными столбцами — волосы мягкие и шелковистые:

> df <- data.frame(time = c(1:10), data = c(10:19))
> df$data[df$time >= 4 & df$time <= 6]

А когда надо порезать матрицу, то даже с заведомо известными столбцами код превращается в мешанину:

> mx <- cbind(time = c(1:10), data = c(10:19))
> mx[mx[,"time"] >= 4 & mx[,"time"] <= 6, "data"]
Stil ★★★★★
() автор топика
Ответ на: комментарий от Stil
Prelude> :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

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

yoghurt ★★★★★
()
Ответ на: комментарий от Stil

Вот кстати научи делать слайсы...

уже сказали про plyr

но есть еще полезный dsl для агрегации, это «сладкая парочка» melt и cast (лучше сразу reshape2)

psv1967 ★★★★★
()
Ответ на: комментарий от psv1967

вопрос должен звучать как, «т.е. mapply это zipWith, который не проверяет типы»? Да, mapply это почти, что zipWith, во всяком случае так же применяет типы, однако далее есть разница, mapply не фьюзится (промежуточные структуры создаются), mapply не ленивый (ну, если честно, в R есть подобие ленивости, но серьёзно его рассматривать нельзя).

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

1) mapply() не ленивый, поскольку вызывается сишная реализация без ленивости

2) а ленивость в R почти никто не учитывает когда пишет код :(

psv1967 ★★★★★
()
Ответ на: комментарий от Interlace

Можно же функцию diff() использовать.

для "-" да, но вопрос был для произвольной пользовательской функции?

psv1967 ★★★★★
()
Ответ на: комментарий от psv1967
> system.time(mapply("-",x[-1],x[-length(x)])[1])
пользователь      система       прошло 
       4.164        0.032        4.200 
> system.time("-"(x[-1],x[-length(x)])[1])
пользователь      система       прошло 
       0.084        0.004        0.088 
> system.time(diff(x)[1])
пользователь      система       прошло 
       0.088        0.000        0.087 

psv1967 ★★★★★
()
Последнее исправление: psv1967 (всего исправлений: 1)
Ответ на: комментарий от psv1967

но вопрос был для произвольной пользовательской функции?

Да

Stil ★★★★★
() автор топика
Ответ на: комментарий от psv1967

Для сравнения корректнее использовать microbenchmark всё же - повторения и случайность попыток нивелируют многие побочные эффекты.

unikum ★★★★★
()
Ответ на: комментарий от psv1967

Так и запишем: не критичен к собственному состоянию :)

unikum ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.