How to divide group in R - r

If I have a series like this:
s={9, 4, 6, 5, 3, 10, 5, 3, 5)}
I want to divide the group by the number 5
at the end , it has to be
s1={9, 4, 6, 5}
s2={5, 3, 10, 5}
s3={5, 3, 5}
I have already tried
cut(ss,ss==5)
what am i supposed to do?
what function that i can use?

Here's an approach to generate a list containing the three vectors:
# the original vector
s <- c(9, 4, 6, 5, 3, 10, 5, 3, 5)
# an index vector
idx <- unique(c(1, which(s == 5), length(s)))
# create a list
mylist <- lapply(seq(length(idx) - 1), function(i) s[idx[i]:idx[i+1]])
mylist
# [[1]]
# [1] 9 4 6 5
# [[2]]
# [1] 5 3 10 5
# [[3]]
# [1] 5 3 5
You can access the list elements with [[, e.g., mylist[[1]] for the first vector.

Related

How to identify each integer sequence regardless of ties in a vector

This question is related to this identify whenever values repeat in r
While searching for answer there this new question arose:
I have this vector:
vector <- c(1, 1, 2, 3, 5, 6, 6, 7, 1, 1, 1, 1, 2, 3, 3)
I would like to identify each consecutive (by 1) integer sequence e.g. 1,2,3,.. or 3,4,5,.. or 4,5,6,7,...
BUT
It should allow ties 1,1,2,3,.. or 3,3,4,5,... or 4,5,5,6,6,7
The expected output would be a list like:
sequence1 <- c(1, 1, 2, 3)
sequence2 <- c(5, 6, 6, 7)
sequence3 <- c(1, 1, 1, 1, 2, 3, 3)
So far the nearest approach I found here Check whether vector in R is sequential?, but could not transfer it to what I want.
An option is with diff and cumsum
split(vector, cumsum(c(TRUE, abs(diff(vector)) > 1)))
-output
`1`
[1] 1 1 2 3
$`2`
[1] 5 6 6 7
$`3`
[1] 1 1 1 1 2 3 3

How to select a random vector

I have 4 vectors that contain integers.
I want to perform calculations based on 2 of the vectors, selected randomly.
I tried creating a new vector containing all the vectors, but sample() only gives me the first element of each vector.
My vectors if it helps:
A <- c(4, 4, 4, 4, 0, 0)
B <- c(3, 3, 3, 3, 3, 3)
C <- c(6, 6, 2, 2, 2, 2)
D <- c(5, 5, 5, 1, 1, 1)
The output I wanted is for example: A, B or B, D or D, A etc.
A thousand thanks in advance!
This is easier to do if you store your vectors in a list:
vecs <- list(
A = c(4, 4, 4, 4, 0, 0),
B = c(3, 3, 3, 3, 3, 3),
C = c(6, 6, 2, 2, 2, 2),
D = c(5, 5, 5, 1, 1, 1)
)
idx <- sample(1:length(vecs), 2, replace = F)
sampled <- vecs[idx]
sampled
$D
[1] 5 5 5 1 1 1
$B
[1] 3 3 3 3 3 3
You can then access your two sampled vectors, regardless of their names, with sampled[[1]] and sampled[[2]].
You first need make a list or a dataframe, on which you can do sample(). size= says the number of vectors that you want in each sample, which is 2 here.
LIST
> LIST <- list(A, B, C, D)
> sample(LIST, size = 2)
[[1]]
[1] 3 3 3 3 3 3
[[2]]
[1] 4 4 4 4 0 0
Dataframe
> df <- data.frame(A, B, C, D)
> sample(df, size = 2)
B C
1 3 6
2 3 6
3 3 2
4 3 2
5 3 2
6 3 2
I think you were sampling on the wrong object.
Make a list:
LIST = list(A,B,C,D)
names(LIST) = c("A","B","C","D")
This gives you a sample of 2 from the list
sample(LIST,2)
To add them for example, do:
Reduce("+",sample(LIST,2))

Finding Values Present in Two or More Unequal-Length Vectors

I have the following two numeric vectors:
A <- c(1, 3, 5, 7, 9)
B <- c(2, 3, 4, 5, 6, 10, 12, 13)
I want to generate a new vector C that contains the values that are present in both A and B (not the positions at which these values are found). The result should be:
C <- c(3, 5)
I also want to generate a vector D containing the values present in A but not present in B and a vector E containing the values present in B but not A.
D <- c(1, 7, 9)
E <- c(2, 4, 6, 10, 12, 13)
What is the best way to do this using base R? Thanks!
You can use the base R function intersect().
In addition, generally speaking I wouldn't use C as a variable name as it really close to c(), which might cause you problems.
A <- c(1, 3, 5, 7, 9)
B <- c(2, 3, 4, 5, 6, 10, 12, 13)
Inter <- intersect(A, B)
[1] 3 5
For the opposite of `intersect()':
#taken from here:https://www.r-bloggers.com/outersect-the-opposite-of-rs-intersect-function/
outersect <- function(x, y) {
sort(c(setdiff(x, y),
setdiff(y, x)))
}
outersect(A, B)
[1] 1 2 4 6 7 9 10 12 13
A <- c(1, 3, 5, 7, 9)
B <- c(2, 3, 4, 5, 6, 10, 12, 13)
C <- A[!A%in%B]
D <- B[!B%in%A]
Which yields
> C
[1] 1 7 9
> D
[1] 2 4 6 10 12 13

How to drop a value from a list if it is not present in any other list

Say, for example, I have 5 lists named a, b, c, d, e. List a contains [1, 2, 3, 4, 5], list b contains [2, 3, 4, 5, 6], list c contains [2, 3, 5, 6, 7], list d contains [2, 4, 5], list e contains [3, 5, 7].
The data I am working with is much more complex, so I need to find a way to read each value from each list, check if it is present in any other lists, and if not, drop it from the original list. So when it reads list a, it sees that "1" is not present in any of the other lists, so "1" should be dropped from list a.
How would I go about doing this?
Thanks!
# assuming you have a list of lists
a=list(1, 2, 3, 4, 5);b=list(2, 3, 4, 5, 6);c=list(2, 3, 5, 6, 7);d=list(2,4,5);e=list(3,5,7)
my_list = list(a,b,c,d,e)
# first unlist each list
my_list = lapply(my_list,unlist)
n=length(my_list)
new_list = lapply(seq(n), function(x)
{my_list[[x]][my_list[[x]] %in% unlist(my_list[-x])]})
Output:
[[1]]
[1] 2 3 4 5
[[2]]
[1] 2 3 4 5 6
[[3]]
[1] 2 3 5 6 7
[[4]]
[1] 2 4 5
[[5]]
[1] 3 5 7
Like this:
a <- c(1, 2, 3, 4, 5)
b <- c(2, 3, 4, 5, 6)
c <- c(2, 3, 5, 6, 7)
d <- c(2, 4, 5)
e <- c(3, 5, 7)
Retain only the values that are in other vectors:
a[a %in% b | a %in% c | a %in% d | a %in% e]
[1] 2 3 4 5

Merging two consecutive values

I have a vector of different values, and I would like to merge and add two values together if a 5 is followed by a 3.
Input:
vector <- c(1, 2, 7, 4, 3, 8, 5, 3, 2, 6, 9, 4, 4, 5, 6, 2, 6, 5, 3)
Expected output:
1 2 7 4 3 8 8 2 6 9 4 4 5 6 2 6 8
So as you can see, the two occurrences of a three following a 5 have been added together to show 8. I'm sure there is a simple function that will do this in a matter of seconds, I just wasn't able to find it.
Thanks in advance!
vector <- c(1, 2, 7, 4, 3, 8, 5, 3, 2, 6, 9, 4, 4, 5, 6, 2, 6, 5, 3)
# get indices where 5 followed by 3
fives <- head(vector, -1) == 5 & tail(vector, -1) == 3
# add three to fives
vector[fives] <- vector[fives] + 3
# remove threes
vector <- vector[c(TRUE, !fives)]
vector
# [1] 1 2 7 4 3 8 8 2 6 9 4 4 5 6 2 6 8
Here is one possibility:
x <- c(1, 2, 7, 4, 3, 8, 5, 3, 2, 6, 9, 4, 4, 5, 6, 2, 6, 5, 3)
A <- rbind(x[-length(x)], x[-1])
id <- which( colSums( abs(A - c(5, 3)) ) == 0 )
x[rbind(id, id + 1L)] <- c(8, NA)
na.omit(x)
This solution was proposed to make it easier to extend to general cases (It may not best meets OP's need, but I just did it as an exercise.)
In general, if you want to match a chunk xc in a vector x, we can do:
A <- t(embed(x, length(xc)))
id <- which(colSums(abs(A - rev(xc))) == 0)
Now id gives you the starting index of the matching chunk in x.
vector <- c(1, 2, 7, 4, 3, 8, 5, 3, 2, 6, 9, 4, 4, 5, 6, 2, 6, 5, 3)
temp = rev(which((vector == 5) & (vector[-1] == 3))) # find indexes of 5s followed by 3s
for (t in temp){
vector = vector[-(t+1)] # remove threes
vector[t] = 8 # replace fives with eights
}
vector
# [1] 1 2 7 4 3 8 8 2 6 9 4 4 5 6 2 6 8

Resources