Matrix Indexing R [duplicate] - r

This question already has answers here:
Subset a matrix according to a columns vector
(2 answers)
Closed 7 years ago.
I'm trying to index a matrix in R using this code:
test <- matrix(0, nrow = 10, ncol = 2)
test[1:10, 1] <- 1:10
test[1:10, 2] <- 11:20
index <- c(1,2,1,1,2,1,1,2,1,2)
answer <- test[ , index]
I receive a 10 x 10 matrix. But I would like to receive a vector.
[1] 1 12 3 4 15 6 7 18 9 20
Any ideas?
Edit:
Also, how one could use exclusionary indexing (e.g., -index) to exclude values from the matrix.
[1] 11 2 13 14 5 16 17 8 19 10

We need row/column indexing to extract the element by the corresponding position. For that we can cbind the row sequence with the column 'index' and get the elements.
test[cbind(seq_len(nrow(test)), index)]
#[1] 1 12 3 4 15 6 7 18 9 20

Related

R - Remove elements in a vector that appear more than once [duplicate]

This question already has answers here:
R - Filter a vector using a function
(5 answers)
Closed 2 years ago.
Let's say I have the following vector
vec <- rep(1:20,sample(1:5, 20, replace = T))
table(vec)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 5 4 3 5 2 1 1 3 5 3 2 3 1 5 5 3 1 4 1
I want to only keep the numbers that appear once. Anything that appears more than once, I want to remove it. So in the end I'd like to end up with
1 7 8 14 18 20
At the moment, I'm generating this with the following command
vec2 <- names(which(table(vec) == 1))
vec2
But I'm wondering if there's a beeter (and more efficient) way of doing this.
We can use %in% and negate (!) create a logical vector based on the OP's code
vec[!vec %in% vec2]
Or in a single line using ave and length
vec[ave(seq_along(vec), vec, FUN = length)>1]

Element wise subtraction of a vector? [duplicate]

This question already has an answer here:
subtract every value in a vector from every other value in the vector R
(1 answer)
Closed 2 years ago.
I have the following vector in R
x<-c(5,7,8,20,11,30)
I want to get all the possible subtractions xi-xj, 1<=i<j<=6. I used outer function but I got a matrix with zero diagonal. I do not want to have xi-xj with i=j. Additionally, I want to have a vector, not a matrix.
You can subset the output of outer using lower.tri or upper.tri.
y <- outer(x, x, '-')
y[lower.tri(y)]
# [1] 2 3 15 6 25 1 13 4 23 12 3 22 -9 10 19
Alternatively you can generate the indices using seq and rep.
k <- seq(length(x) - 1, 1)
i <- rep(seq_along(k), k)
j <- sequence(k) + i
x[j] - x[i]
# [1] 2 3 15 6 25 1 13 4 23 12 3 22 -9 10 19
Yes, outer generates a matrix with all possible combinations in both the directions (a - b and b - a) which is unnecessary in this case.
Perhaps, you can use combn :
combn(x, 2, diff)
#[1] 2 3 15 6 25 1 13 4 23 12 3 22 -9 10 19
Also as #Rui Barradas points out that outer might not be the right solution since it fails for the condition 1<=i<j<=6.
Higher order functions; less succinct/readable than above but quicker for some reason.
Filter(function(y) {y != 0},
do.call("c", (Map(function(i){y <- x - x[i]; y[i:length(x)]}, seq_along(x)))))

Split a vector into subverter of the same length and assign each of them to a new vector [duplicate]

This question already has answers here:
Split a vector into chunks
(22 answers)
Closed 1 year ago.
Suppose that I have a vector as this:
s <- c(1:30) ## here the numbers are just an example. I just need to split it into the same length subvectors.
Then, suppose that I have other three vectors:
s1 <- s2 <- s3 <- vector()
I would like to split the first vector s into three subvectors each with 10 elements. Then, I would like to save each 10 elements in the vectors s1:s3. For example,
I would like to have this:
> s1
[1] 1 2 3 4 5 6 7 8 9 10
> s2
[1] 11 12 13 14 15 16 17 18 19 20
> s3
[1] 21 22 23 24 25 26 27 28 29 30
I would like to do that with lapply because sometimes I need to split the vector to 10, 3 or any arbitrary number of subvectors depends on my data.
We can split the vector 's' with a grouping index created with gl. The output will be a list and it is better to keep it in the list instead of multiple objects in the global environment
lst <- split(s, as.integer(gl(length(s), 10, length(s))))
gl creates a grouping vector
as.integer(gl(length(s), 10, length(s)))
#[1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3
and when split the 's' by the output of gl, the first 10 values of 's' are grouped together, then the second 10 and so on. These are stored as list of vectors

Create all possible combinations from two values for each element in a vector in R [duplicate]

This question already has answers here:
How to generate a matrix of combinations
(3 answers)
Closed 6 years ago.
I have been trying to create vectors where each element can take two different values present in two different vectors.
For example, if there are two vectors a and b, where a is c(6,2,9) and b is c(12,5,15) then the output should be 8 vectors given as follows,
6 2 9
6 2 15
6 5 9
6 5 15
12 2 9
12 2 15
12 5 9
12 5 15
The following piece of code works,
aa1 <- c(6,12)
aa2 <- c(2,5)
aa3 <- c(9,15)
for(a1 in 1:2)
for(a2 in 1:2)
for(a3 in 1:2)
{
v <- c(aa1[a1],aa2[a2],aa3[a3])
print(v)
}
But I was wondering if there was a simpler way to do this instead of writing several for loops which will also increase linearly with the number of elements the final vector will have.
expand.grid is a function that makes all combinations of whatever vectors you pass it, but in this case you need to rearrange your vectors so you have a pair of first elements, second elements, and third elements so the ultimate call is:
expand.grid(c(6, 12), c(2, 5), c(9, 15))
A quick way to rearrange the vectors in base R is Map, the multivariate version of lapply, with c() as the function:
a <- c(6, 2, 9)
b <- c(12, 5, 15)
Map(c, a, b)
## [[1]]
## [1] 6 12
##
## [[2]]
## [1] 2 5
##
## [[3]]
## [1] 9 15
Conveniently expand.grid is happy with either individual vectors or a list of vectors, so we can just call:
expand.grid(Map(c, a, b))
## Var1 Var2 Var3
## 1 6 2 9
## 2 12 2 9
## 3 6 5 9
## 4 12 5 9
## 5 6 2 15
## 6 12 2 15
## 7 6 5 15
## 8 12 5 15
If Map is confusing you, if you put a and b in a list, purrr::transpose will do the same thing, flipping from a list of two elements of length three to a list of three elements of length two:
library(purrr)
list(a, b) %>% transpose() %>% expand.grid()
and return the same thing.
I think what you're looking for is expand.grid.
a <- c(6,2,9)
b <- c(12,5,15)
expand.grid(a,b)
Var1 Var2
1 6 12
2 2 12
3 9 12
4 6 5
5 2 5
6 9 5
7 6 15
8 2 15
9 9 15

Is there a construct similar to ifelse() which returns all the elements and not only the first one? [duplicate]

This question already has answers here:
Why can't R's ifelse statements return vectors?
(9 answers)
Closed 6 years ago.
In the following example, how can i.want.them.all get all the 10 numbers from 5 to 14?
control.me <- 0 # or 1
a.lot.of.elements <- c(5:14)
i.want.them.all <- ifelse(control.me == 1, a.lot.of.elements, a.lot.of.elements - 10)
print(i.want.them.all)
[1] 5
Is there a construct that works like this? :
a.lot.of.elements <- c(5:14)
i.want.them.now <- magic.construct(control.me == 1, a.lot.of.elements, a.lot.of.elements - 10)
print(i.want.them.now)
[1] 5 6 7 8 9 10 11 12 13 14
If not, how could I accomplish what I want to do?
Perhaps just testing seq_along since any positive integer will always evaluate to TRUE:
> i.want.them.now <- ifelse(seq_along(a.lot.of.elements), a.lot.of.elements, character())
> i.want.them.now
[1] 5 6 7 8 9 10 11 12 13 14

Resources