Reorder a vector with wrap around in R - r

Let's say I have a simple vector x in R. It is in the order 'a','b','c','d'. Is there a function that would take the vector and reorder it with wrap around? For example, how can I get x to be 'c','d','a','b'?
#Vector x
> x <- letters[1:4]
> x
[1] "a" "b" "c" "d"
#What I want:
> somefcn(x, 3)
[1] "c" "d" "a" "b"

x <- letters[1:4]
shiftnum <- 3
c(x[shiftnum:length(x)],x[1:shiftnum-1])
[1] "c" "d" "a" "b"
Is a very rough way to do, but it works

Related

R: Non-greedy version of setdiff?

Here's setdiff normal behaviour:
x <- rep(letters[1:4], 2)
x
# [1] "a" "b" "c" "d" "a" "b" "c" "d"
y <- letters[1:2]
y
# [1] "a" "b"
setdiff(x, y)
# [1] "c" "d"
… but what if I want y to be taken out only once, and therefore get the following result?
# "c" "d" "a" "b" "c" "d"
I'm guessing that there is an easy solution using either setdiff or %in%, but I just cannot see it.
match returns a vector of the positions of (first) matches of its first argument in its second. It's used as an index constructor:
x[ -match(y,x) ]
#[1] "c" "d" "a" "b" "c" "d"
If there are duplicates in 'y' and you want removal in proportion to their numbers therein, then the first thing that came to my mind is a for-loop:
y <- c("a","b","a")
x2 <- x
for( i in seq_along(y) ){ x2 <- x2[-match(y[i],x2)] }
> x2
[1] "c" "d" "b" "c" "d"
This would be one possible result of using the tabling approach suggested below. Uses some "set" functions, but this is not really a set problem. Seems somewhat more "vectorised":
c( table(x [x %in% intersect(x,y)]) - table(y[y %in% intersect(x,y)]) ,
table( x[!x %in% intersect(x,y)]) )
a b c d
0 1 2 2
vecsets package has vsetdiff function for this.
x <- rep(letters[1:4], 2)
y <- letters[1:2]
vecsets::vsetdiff(x, y)
#[1] "c" "d" "a" "b" "c" "d"
Here is another looping method. I think 42's method is cleaner, but it provides another option.
# construct a table containing counts for all possible values in x and y in y
myCounts <- table(factor(y, levels=sort(union(x, y))))
# extract these elements from x
x[-unlist(lapply(names(myCounts),
function(i) which(i == x)[seq_len(myCounts[i])]))]
The "non-greedy" aspect comes from [seq_len(myCounts[i])] which only takes the number of identical elements that are present in y

R remove an object from a list of vectors

I have a list of vectors and i would like to remove a specific object. Any ideas hot to achieve that?
Lets say i would like to remove the object F. How can i do that?
blocks <- list(
c("A", "B"),
c("C"),
c("D","E", "F")
)
We could also use setdiff with Map
Map(setdiff, blocks, 'F')
#[[1]]
#[1] "A" "B"
#[[2]]
#[1] "C"
#[[3]]
#[1] "D" "E"
or with lapply
lapply(blocks, setdiff, 'F')
#[[1]]
#[1] "A" "B"
#[[2]]
#[1] "C"
#[[3]]
#[1] "D" "E"
If you wanted to remove the third element of the third element of your list, you could try:
blocks[[3]] <- blocks[[3]][-3]
blocks
# [[1]]
# [1] "A" "B"
#
# [[2]]
# [1] "C"
#
# [[3]]
# [1] "D" "E"
If you wanted to remove all elements equal to "F", you could use lapply and a user-defined function to process each vector in the list, removing all "F" elements.
lapply(blocks, function(x) x[x != "F"])
# [[1]]
# [1] "A" "B"
#
# [[2]]
# [1] "C"
#
# [[3]]
# [1] "D" "E"

R construct summary of values from columns

I would like to make an array that summarises the rows of a data frame with the unique values contained within said rows.
with sample the following example code:
ref <- c(1:8)
data1 <- c("A","","C","","","","A","")
data2 <- c("A","","","A","C","","","")
data3 <- c("","B","","","","","","B")
data4 <- c("A","B","","","","D","A","")
initial.data <- data.frame(ref, data1, data2, data3, data4)
I can obtain what I want with:
summary.data <- paste(initial.data[,2], initial.data[,3],
initial.data[,4], initial.data[,5], sep='')
desired.data <- substring(summary.data,1,1)
However, I would like a more parsimonious way of coding this and one that does not assume that each row may only take one value.
You can try
apply(initial.data[-1],1, function(x) unique(x[x!='']))
#[1] "A" "B" "C" "A" "C" "D" "A" "B"
Or
substr(do.call(paste0, initial.data[-1]),1,1)
#[1] "A" "B" "C" "A" "C" "D" "A" "B"
Or use max.col
initial.data[cbind(1:nrow(initial.data),max.col(initial.data[-1]!='')+1)]
#[1] "A" "B" "C" "A" "C" "D" "A" "B"

obtain the position of elements of Y that a are in X in R

In R,
I have a vector of 5 unique elements:
X<-c("A","B","C","D","E")
And a vector of repeated elements:
Y<- c("A","C","M","Z","B","C","C","R","V","D","D","B","A","V","E","E")
I want to obtain the position of elements of Y that a are in X becase Y are rownames of a matrix.
But Y[match(Y,X)] gives:
[1] "A" "M" NA NA "C" "M" "M" NA NA "Z" "Z" "C" "A" NA "B" "B"
The response should be:
c("A","C",NA,NA,"B","C","C",NA,NA,"D","D","B","A",NA,"E","E").
to select the rows:
Y[-which(is.na(Y[match(Y,X)]))]
Is there a better and more elegant alternative?
You can use %in%:
Y[Y %in% X]
[1] "A" "C" "B" "C" "C" "D" "D" "B" "A" "E" "E"
Does this help?

R: Inverse of factor interaction

I'm having a great deal of trouble with the following problem, and can't seem to find an answer with extensive searching. If I have the following:
> fac1 <- factor(c("a", "b", "c"))
> fac2 <- factor(c("d", "e", "f"))
> fac3 <- interaction(fac1,fac2)
> fac3
[1] a.d b.e c.f
Levels: a.d b.d c.d a.e b.e c.e a.f b.f c.f
What function can I run to split fac3 so that I obtain the levels of the original factors put into the interaction? So that:
> myFun(fac3, 1)
[1] "a" "b" "c" "a" "b" "c" "a" "b" "c"
> myFun(fac3, 2)
[2] "d" "d" "d" "e" "e" "e" "f" "f" "f"
Thanks.
> myFun <- function(fac, idx) sapply( strsplit(as.character(fac), "\\."), "[", idx)
> myFun(fac3,1)
[1] "a" "b" "c"
> myFun(fac3,2)
[1] "d" "e" "f"
Depending on what you wanted to do with these vectors you could wrap factor() around the results. There is some ambiguity in your question. Looking at #user1317221's contribution I see that it does return what you said you wanted but when you said you wanted the levels of the factor, I thought you wanted vectors only as long as 'fac3' which had three elements, despite having a longer levels attribute.
You could easily turn the following into a function
sapply(strsplit(as.character(fac3), "\\."), "[", 1)
sapply(strsplit(as.character(fac3), "\\."), "[", 2)

Resources