R purrr, can I use two arrays in a modify_if statement? - r

I want to use one array to decide whether or not to modify another, hoping to use modify_if, but there might be a simpler way. Here is my mwe.
vec1 <- array( c(1, 3, 5, 6, 7, 3, 2, 3))
vec2 <- array(c(TRUE, TRUE, FALSE,TRUE, FALSE, FALSE, TRUE, FALSE))
vec1 %<>% purrr::modify_if(~ .x[vec2], vec1 + 1)
So I already have the logical array to tell me which ones to change. If vec2 is TRUE, then I want to modify the value at that index to increment the current value of vec1 by 1, otherwise if vec2 is false then leave in the original value. The result I am looking for is
2, 4, 5, 7, 7, 3, 3, 3. Thx, J.

Within the tidyverse, I think you want
vec1
# [1] 1 3 5 6 7 3 2 3
vec1 %<>% purrr::modify_if(vec2, ~ .x + 1)
vec1
# [1] 2 4 5 7 7 3 3 3
Though as #MartinGal suggested, base R's might be more direct:
vec1 <- array( c(1, 3, 5, 6, 7, 3, 2, 3))
vec1[vec2] <- vec1[vec2] + 1
vec1
# [1] 2 4 5 7 7 3 3 3

Related

How to get the positions of the k greatest(or smallest) elements of a vector? [duplicate]

This question already has answers here:
How to find the largest N elements in a list in R?
(4 answers)
Closed 10 months ago.
I have a vector and I want to find the indices of the k greatest elements, not the elements themselves which I could do with sort. One idea would be to add indices to the values and have a custom sort function that only compares the first elements of pairs (a classical solution to this problem) but surely there has to be a simpler way ? Note that performance isn`t a matter.
First I create a random vector:
vector <- c(1, 3, 6, 2, 7, 8, 10, 4)
Next, you can use the following code which will output the top k elements as x with index ix:
k <- 3
lst <- sort(vector, index.return=TRUE, decreasing=TRUE)
lapply(lst, `[`, lst$x %in% head(unique(lst$x),k))
Output:
$x
[1] 10 8 7
$ix
[1] 7 6 5
As you can see ix gives the index of the top k elements.
Using rank.
x <- c(1, 3, 6, 2, 7, 8, 10, 4)
seq_along(x)[rank(-x) < 4]
# [1] 5 6 7
If you have ties, the result is this:
x <- c(10, 3, 6, 2, 7, 8, 10, 4)
seq_along(x)[rank(-x) < 4]
# [1] 1 6 7

Choose second or third rank in repeated value using R

I have some value of x:
x <- c(12, 5, 6, 7, 8, 5, 8, 7, 5, 6, 9, 10)
p <- x[order(x)]
p
[1] 5 5 5 6 6 7 7 8 8 9 10 12
The smallest value of x is 5, but I want to choose the second of the smallest x (6) or third (7).
How to get it?
We can write a function to get nth smallest value, by considering only unique values of already sorted vector p.
get_nth_smallest_value <- function(n) {
unique(p)[n]
}
get_nth_smallest_value(2)
#[1] 6
get_nth_smallest_value(4)
#[1] 8
Or if we need in terms of only x, we can sort them first, take only unique values and then get the value by it's index.
get_nth_smallest_value <- function(n) {
unique(sort(x))[n]
}
get_nth_smallest_value(2)
#[1] 6
get_nth_smallest_value(3)
#[1] 7

calculating distance between values in vector R

I have the following multiset X, in which I want to find the distances between all the numbers. Is there any way to integrate this into a FOR LOOP so that If I was given a different sized multiset, I wouldn't have to manually do it like i did below?
the final answer IS [0,2, 2, 3, 3, 4, 5, 6, 7, 8, 10] (sorted) for this example
X=c(0,10,8,3,6)
L=length(X)
print(L)
##for(i in seq(from=1, to=L )){}
print(abs(X[1]-X[2]), abs(X[1]-X[3]),
abs(X[1]-X[4]), abs(X[1]-X[5]),
abs(X[1]-X[6]),
abs(X[2]-X[3]), abs(X[2]-X[4]),
abs(X[2]-X[5]), abs(X[2]-X[6]),
abs(X[3]-X[4]), abs(X[3]-X[5]),
abs(X[3]-X[6]),
abs(X[4]-X[5]), abs(X[4]-X[6]),
abs(X[5]-X[6])
)
You may see this vector as a column vector and apply dist:
sort(dist(X))
# [1] 2 2 3 3 4 5 6 7 8 10

Fill Observations that Correspond to a Reference Vector in R

I have two vectors that one (v.num) corresponds to one variable in df and the other one (v.type) is a vector that I want to fill into the df with the corresponding vector.
v.num<-c(5, 6, 7, 8, 9, 10, 11)
v.type<-c(1, 3, 5, 2, 2, 4, 1)
The df looks like this:
set.seed(2016)
df <- data.frame(v.num=sample(5:11, 40000, replace=TRUE), obs=rnorm(40000))
What I want to do is create a v.type vector and store the v.type that corresponds to v.num
Like:
head(df)
v.num obs v.type
1 6 1.6149522 3
2 6 -0.2676644 3
3 10 0.3013365 4
4 5 -0.8514377 1
5 8 0.5786278 2
6 5 -1.2974004 1
I tried
for(i in 1:nrow(df)){
for(v in 1:length(v.num){
if(v.num[v]==df$v.num[i]){df$v.type[i]<-v.type[v]}
}}
But it takes pretty long, because I have 40000 rows. What is the most efficient way to do this task?
Check out the following code:
v.num<-c(5, 6, 7, 8, 9, 10, 11)
v.type<-c(1, 3, 5, 2, 2, 4, 1)
set.seed(2016)
df <- data.frame(v.num=sample(5:11, 40000, replace=TRUE), obs=rnorm(40000))
df$v.type <- v.type[match(df$v.num, v.num)]

How to preserve the order of a vector in a table in R?

Pretty simple question, I assume. I am trying to do this for a different type of object (with class 'acf' and type 'list'), but I assume the answer is easily extendable for a vector (class numeric, type 'double'):
x<-c(4, 5, 6, 1, 2, 10, 15)
table(x)
x
1 2 4 5 6 10 15
1 1 1 1 1 1 1
I would like the output of the table to be in the same order as the vector (4, 5, 6, 1, 2, 10, 15). How can I achieve this?
table(factor(x, levels=unique(x)))

Resources