2015-03-19 4 views
6

У меня довольно простая проблема, которая приносит мне печаль, несмотря на пару часов зависания волос, поэтому я подумал, что попрошу вашу помощь. Я ищу простой способ вернуть вектор, содержащий только последний элемент некоторого исходного вектора.Захват последнего элемента вектора

Это мой исходный вектор, «а»:

a<-c(0,0,1,0,0,1,0,0,1,0) 

Я хочу, чтобы получить вектор «Ъ», который имеет ту же длину, как «а», и несет только его последний nonmissing элемент. Другими словами,

b = (0,0,0,0,0,0,0,0,1,0) 

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

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

Большое спасибо за любую помощь.

ответ

5

Одним из вариантов является

b<- numeric(length(a)) 
b[max(which(a!=0))] <- 1 
b 
#[1] 0 0 0 0 0 0 0 0 1 0 
7

Это просто для удовольствия, как однострочника:

`[<-`(a, rev(which(as.logical(a)))[-1], 0) 
## [1] 0 0 0 0 0 0 0 0 1 0 

И немного другая версия:

`[<-`(integer(length = length(a)), rev(which(a != 0))[1], 1) 
## [1] 0 0 0 0 0 0 0 0 1 0 
6

Я считаю, что это должно работать а также

ifelse(cumsum(a)==sum(a), a, 0) 
# [1] 0 0 0 0 0 0 0 0 1 0 

Это предполагает, что «отсутствующие» значения являются нулями, а значения без пропуска - 1. Если у вас есть другие, чем 1-е значения, вы могли бы сделать

ifelse(cumsum(a!=0)==sum(a!=0), a, 0) 
4

Я немного поздно, но вот еще один вариант:

a[head(which(a == 1), -1)] <- 0 

или

replace(a, head(which(a == 1), -1), 0) 

Бенчмарки

Unit: milliseconds 
     expr  min  lq median  uq max neval 
    akrun() 8.600 9.201 11.346 12.531 68.45 100 
plourde() 9.034 9.767 11.545 12.498 69.33 100 
    flick() 164.792 215.759 221.868 227.237 333.72 100 
    thomas() 4.210 6.427 8.108 9.913 66.65 100 

Функции

akrun <- function() { 
    b<- numeric(length(a)) 
    b[max(which(a!=0))] <- 1 
    b 
} 
plourde <- function() replace(a, head(which(a == 1), -1), 0) 
flick <- function() ifelse(cumsum(a)==sum(a), a, 0) 
thomas <- function() `[<-`(a, rev(which(as.logical(a)))[-1], 0) 
+2

Я нахожу это, чтобы победить их всех: 'заменить (0 * а, which.max (cumsum (а)), 1)'. Интуитивно я считаю, что все, что использует 'which' будет медленным, потому что длина вывода неизвестна заранее. Не относится к 'cumsum' и' which.max'. – flodel

3

Другой простой вариант:

n = max(which(as.logical(a))) - 1 
c(numeric(n), tail(a, -n)) 
Смежные вопросы