Find sequences in vector that do not match a pattern - r

I want to find sequence of elements in vector that do not match a pattern.
For example:
pattern <- c(1,2,3,4)
test <- c(5,4,3,6,1,2,3,4,5,3,3,2,1,2,3,4,6,3,7,5,1,2,3,6)
I want to find whole sequence in "test" that do not match "pattern" or indexes where this situation occurs.
So I want to get a result similar to this:
> want
[[1]]
[1] 5 4 3 6
[[2]]
[1] 5 3 3 2
[[3]]
[1] 6 3 7 5 1 2 3 6
or something like this:
> indexes
[1] 1 9 17
Do you have an idea how to do this?

One option is
lapply(scan(text=gsub(paste(pattern,collapse=""), ",",
paste(test, collapse="")), what="", sep=",", quiet = TRUE),
function(x) as.numeric(unlist(strsplit(x, ""))))
#[[1]]
#[1] 5 4 3 6
#[[2]]
#[1] 5 3 3 2
#[[3]]
#[1] 6 3 7 5 1 2 3 6

Related

How to append elements of an R list to each other, but only the top level?

I need to append lists contained inside a top-level list. Other levels should be preserved, and there should be more than 2 elements possible.
l <- list(list(1:5), list(6:10))
required <- c(l[[1]], l[[2]])
1) We can flatten with c from base R
do.call(c, l)
-output
#[[1]]
#[1] 1 2 3 4 5
#[[2]]
#[1] 6 7 8 9 10
2) Or with unlist with recursive = FALSE. Also a base R solution
unlist(l, recursive = FALSE)
3) Or with lapply (base R)
lapply(l, unlist, recursive = FALSE)
4) Or using Map (another base R)
Map(c, l)
5) Or with flatten from purrr
library(purrr)
flatten(l)
You can also use mapply():
#Code
mapply(c,l)
[[1]]
[1] 1 2 3 4 5
[[2]]
[1] 6 7 8 9 10
Or also lapply():
#Code 2
lapply(l,unlist)
[[1]]
[1] 1 2 3 4 5
[[2]]
[1] 6 7 8 9 10
Or sapply():
#Code 3
sapply(l,c)
[[1]]
[1] 1 2 3 4 5
[[2]]
[1] 6 7 8 9 10
All base R solutions.

Get object and indices from subsetting call

Basically, I would like to create an R function separate_call that gets an argument like x[ind] and returns x and ind (so, from the parent environment):
x <- 1:10
ind <- 2:3
separate_call(x[ind]) ## should return `list(1:10, 2:3)`
I know that I need to use non-standard evaluation and some tree parsing but I'm not familiar enough with these two concepts. Any help would be appreciated.
Looking at the code of pryr:::tree and experimenting a little bit, I found a solution:
separate_call <- function(call) {
call.sep <- as.list(substitute(call))
parent_env <- parent.frame()
x <- eval(call.sep[[2]], parent_env)
ind <- eval(call.sep[[3]], parent_env)
list(x, ind)
}
Verification:
> x <- 1:10
> ind <- 2:3
> separate_call(x[ind])
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[2]]
[1] 2 3
> separate_call(x[1:2])
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[2]]
[1] 1 2
I am adding this solution, not very elegant, see if this fits your need.
separate_call <- function(m){
dprse <- deparse(substitute(m)) ##deparsing the data: to make it as string
lyst <- strsplit(dprse,"\\[|\\]")[[1]] ##removing the square brackets to sparate contents of m
lapply(lyst, function(y)eval(parse(text = y), envir = parent.frame()))
}
I hope this works, I tried it by calling it in three different ways
separate_call(1:10[ind])
separate_call(x[2:3])
separate_call(1:10[2:3])
They all gave me same response
> separate_call(1:10[ind])
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[2]]
[1] 2 3
> separate_call(x[2:3])
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[2]]
[1] 2 3
> separate_call(1:10[2:3])
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[2]]
[1] 2 3

R shuffle lists with repeated elements

I have multiple lists in R, each list has unique elements but some elements are in multiple lists. I want to shuffle the lists but also have each list have only unique elements. Here is something but this doesn't end up with unique lists at the end
x<-list()
x[[1]]<-c(1,2,3,4,5)
x[[2]]<-c(1,2,6,7,8)
u<-unlist(x)
x2<-relist(u[sample(length(u))],skeleton=x)
> x
[[1]]
[1] 1 2 3 4 5
[[2]]
[1] 1 2 6 7 8
> x2
[[1]]
[1] 4 8 3 5 6
[[2]]
[1] 2 1 2 1 7
Trying to figure out extra step to make sure each list has five unique numbers.
In your example the vectors already contain only unique values, so I think the solution can be as simple as:
x <- list(c(1,2,3,4,5), c(1,2,6,7,8))
lapply(x, sample)
# [[1]]
# [1] 3 2 5 1 4
#
# [[2]]
# [1] 1 6 7 2 8

Constant subset of a variable length list for some list[[x]] in R

Imagine the following data:
listA
[[1]]
[1] 1 2 3 4 5 6 7
[[2]]
[1] 1 2 3 4 5 6
[[3]]
[1] 1 2 3 4 5
How to select:
listA[[1:2]][1:4]
Using 1:2 there is not allowed, so is there any way to select these when it is known that this selection exists (both the 1:2 and 1:4 parts)?
What I would like returned:
listA
[[1]]
[1] 1 2 3 4
[[2]]
[1] 1 2 3 4
What about just using lapply,
R> l = list(A = 1:6, B=1:4, C = 1:5)
R> lapply(l[1:2], "[", 1:4)
$A
[1] 1 2 3 4
$B
[1] 1 2 3 4
You probably have to use lapply.
lapply(listA, function(x) x[1:4])
If your actual list is longer, you can access the first two elements of listA by listA[1:2]. So this should work:
lapply(listA[1:2], function(x) x[1:4])

How to output the data with different lengths

R Version 2.11.1 32-bit on Windows 7
I'm wondering if anyone else has encountered this question. I got several arrays with different lengths, and I want put them together to output. For example:
a=c(1,2,3);
b=c(2,4,1,6)
c=c(4,5,9,2,8)
ra=rank(a);#ra=1 2 3
rb=rank(b);#rb=2 3 1 4
rc=rank(c);#rc=2 3 5 1 4
then how to put ra, rb and rc together to be this:
1 2 3
2 3 1 4
2 3 5 1 4
Yes, list() may be help, but how could I save it to my PC.
I tred to use write.table(), but fail.
Transform list to matrix of strings.
a=c(1,2,3);
b=c(2,4,1,6)
c=c(4,5,9,2,8)
rlist <- lapply(list(a,b,c), rank)
m <- do.call(rbind, lapply(rlist,
function(x) paste(x,collapse=" ")
)
)
write.table(m,file="file_name")
Sounds like you want a list.
> list(ra, rb, rc)
[[1]]
[1] 1 2 3
[[2]]
[1] 2 3 1 4
[[3]]
[1] 2 3 5 1 4
> rlist <- lapply( list(a,b,c), rank)
> rlist
[[1]]
[1] 1 2 3
[[2]]
[1] 2 3 1 4
[[3]]
[1] 2 3 5 1 4

Resources