remove a list of specific values from another list - r

I am trying to remove a list of specific values from another list but I cannot find any resources to help me do so.
list1 <- list("a","b", "c", "d", "e", "f", "g","h", "i", "j", "k")
list2 <- list("a","b","c","d")
list3 <- list1[-list2]
I would hope to get an output of the first list without a,b,c, or d. Instead I get
Error in -list2 : invalid argument to unary operator

We can use setdiff as the list elements have length 1
setdiff(list1, list2)
Or use %in% and negate (!)
list1[!list1 %in% list2]

Related

Removing list items based on presence of a sub-list

I have a list and I would like to remove any list object with a sublist. In the example below, I would like to remove ob2 and ob5 and keep all other objects.
dat <- list(ob1 = c("a", "b", "c"),
ob2 = list(a = c("d")),
ob3 = c("e", "f", "g"),
ob4 = c("h", "i", "j"),
ob5 = list(1:3))
Can anyone offer a solution of how to do this?
We can create a condition with sapply (from base R)
dat[!sapply(dat, is.list)]
Or with Filter from base R
Filter(Negate(is.list), dat)
Or with discard
library(purrr)
discard(dat, is.list)

Find vector of strings in list (R)

I have a list, in which each element is a vector of strings, as:
l <- list(c("a", "b"), c("c", "d"))
I want to find the index of the element in l that contains a specific vector of strings, as c("a", "b"). How do I do that? I thought which(l %in% c("a", "b")) should work, but it returns integer(0) instead of 1.
%in% checks presence of elements of the LHS among elements of the RHS. To treat c("a", "b") as a single element of the RHS, it needs to be in a list:
which(l %in% list(c("a", "b")))
Other possibilities are to go element-by-element through l with sapply, such as
which(sapply(l,function(x) all(c("a","b") %in% x)))
# order doesn't matter, other elements allowed
which(sapply(l, identical, c("a", "b"))) # exact match, in order

How to merge only specific elements of a vector in R

This is probably pretty straightforward but I'm really stuck: Let's say that I have a vector=c("a", "b", "c","d","e"). How can I concatenate only some specific elements? For example, how do I merge "b" and "c", which will lead me to the vector=c("a","bc","d","e") ?
Thank you
We can do
i1 <- vector %in% c("b", "c")
c(vector[!i1], paste(vector[i1], collapse=""))

R , Replicating the rownames in data.frame

I have a data.frame with dimension [6587 37] and the rownames must repeat after every 18 rows. How i can do this in Rstudio.
If your 18 column names are:
mynames <- c("a", "b", "c", "d", "e", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s")
You can get what you want with:
paste0(rep(mynames,length.out=6587),rep(1:366,each=18,length.out=6587))
Or you can modify the names pasting different things.
Row names in data.frames have to be unique.
> df <- data.frame(x = 1:2)
> rownames(df) <- c("a", "a")
Error in `row.names<-.data.frame`(`*tmp*`, value = value) :
duplicate 'row.names' are not allowed
In addition: Warning message:
non-unique value when setting 'row.names': ‘a’
You could use make.names to make the names unique, but still carry some repeating information.
> make.names(c("a","a"), unique = TRUE)
[1] "a" "a.1"
These could be identified with help from grep
Or you could make a column in df or a second data.frame that holds the information

Collapse vector to string of characters with respective numbers of consequtive occurences

I would like to collapse a CIGAR vector to a CIGAR string. By CIGAR vector to String I mean the following:
I want a function that converts:
cigar.vector = c("M", "M", "I", "I", "M", "I", "", "M", "D", "D", "M", "I", "D", "M", "I")
to this:
cigar.string = "2M2I1M1I1M2D1M1I1D1M1I"
and viceversa.
Note that there is a "" (empty character), that does not count. thanks!
rle seems the obvious choice here:
rcv <- rle(cigar.vector[cigar.vector!=""])
paste0(rcv$lengths,rcv$values,collapse="")
#[1] "2M2I1M1I1M2D1M1I1D1M1I"
If you want to get fancy, you could also exploit the fact that rle gives a list of length 2:
paste(do.call(rbind,rle(cigar.vector[cigar.vector!=""])),collapse="")
#[1] "2M2I1M1I1M2D1M1I1D1M1I"
Going backwards will be impossible if only given the result (assign above to result), as it has lost information for the "" cases. Excluding those cases, you can get close enough with something like:
backwards <- rep(
unlist(strsplit(result,"\\d+"))[-1],
as.numeric(unlist(strsplit(result,"[^0-9]")))
)
identical(cigar.vector[cigar.vector!=""],backwards)
#[1] TRUE

Resources