Chargaff
Chargaff

Reputation: 1572

Replace element in vector if element is x and previous element is na, in R

foo <- c("a","a",NA,"b","a","a","b","b")

How to replace "b" by whatever if previous element is NA ?

foo[foo=="b" & "previous-element"==NA] <- "whatever"

So expected output would be :

result <- c("a","a",NA,"whatever","a","a","b","b")

So only "b" (many in real datas) preceded by NA would be changed.

Thank's for helping !

Upvotes: 2

Views: 630

Answers (3)

Sven Hohenstein
Sven Hohenstein

Reputation: 81693

A simple solution:

foo[-1][foo[-1] == "b" & is.na(head(foo, -1))] <- "whatever"

Update:

A solution with rollapply from the zoo package:

library(zoo)
foo[-1][rollapply(foo, 2, identical, c(NA, "b"))] <- "whatever"

Upvotes: 7

thelatemail
thelatemail

Reputation: 93813

A totally convoluted solution using embed just for fun:

foo[which(
          apply(
                embed(foo,2),
                1,
                function(x) x[1]=="b" & is.na(x[2])
               )
         ) + 1
    ] <- "whatever"

> foo
[1] "a" "a" NA "whatever" "a" "a" "b" "b"      

Upvotes: 2

Gavin Simpson
Gavin Simpson

Reputation: 174778

Here is one way

foo <- c("a","a",NA,"b","a","a","b","b")

nas <- which(is.na(foo))  ## which are NA
bs <- which(foo == "b")   ## which are "b"

## the match() finds the index in nas that matches the one in bs - 1
foo[bs[match(nas, bs - 1)]] <- "whatever"
foo

The result is

> foo
[1] "a"        "a"        NA         "whatever" "a"       
[6] "a"        "b"        "b"

Wrap this into a function for ease of use:

whatever <- function(x) {
  nas <- which(is.na(x))
  bs <- which(x == "b")
  x[bs[match(nas, bs - 1)]] <- "whatever"
  x
}

which gives

> foo <- c("a","a",NA,"b","a","a","b","b")
> whatever(foo)
[1] "a"        "a"        NA         "whatever" "a"       
[6] "a"        "b"        "b"

Upvotes: 2

Related Questions