How to remove an element by name from a named vector? - r

How to remove an element from a named vector by name? e.g.
v <- c(1, 2, 3)
names(v) <- c('a', 'b', 'c')
# how to remove b?
v['b'] <- NULL # doesn't work
Error in v["b"] <- NULL : replacement has length zero

You could use
v[names(v) != "b"]
#a c
#1 3
Or with setdiff
v[setdiff(names(v), "b")]

Or we can use an index with match
v[-match("b", names(v))]

Related

An if statement returns a different variable on each branch, how can I assign to that variable using only one <- operator?

Consider
if(sample(2, 1) == 1) a <- 5 else b <- 5
This is repetitive. Is there any way to not have to write <- 5 twice?
You may use assign -
assign(if(sample(2, 1) == 1) 'a' else 'b', 5)
We can use list2env
list2env(setNames(list(5), c('a', 'b')[sample(2, 1)]), .GlobalEnv)
-checking
> a
[1] 5

R loop to list all the values of a variable

As an exercice, I have to create a vector of all the different values of a variable (a$dep).
This vector can be created with the code: unique(a$dep)
I need to create this vector using a for loop
I wrote a loop that doesn't give the right result but I don't understand where is the problem:
v<-vector()
for (i in seq_along(a$dep)){
v<-ifelse(a$dep[i] %in% v, v,c(v,a$dep[i]))
}
Thank you very much for your help !
Based on the description, if we need unique values an if condition is sufficient i.e. loop over the sequence of 'dep' column if the element is not (!) %in% 'v', append that element to 'v' and update the 'v' by assignment (<-)
v <- vector()
for(i in seq_along(a$dep)) {if(!a$dep[i] %in% v) v <- c(v, a$dep[i])}
As ifelse requires all arguments to be of same length, 'v' is dynamic in length as we concatenate elements to it, thus, the 'yes', 'no' (always length 1 -a$dep[i]) mismatches in length.
One option with ifelse would be to initiate a vector 'v' with the same length as the 'dep' column length, then use ifelse to check whether the 'dep' element is %in% the whole vector (return TRUE/FALSE - length 1), then return blank (yes - "" - length 1) or else return the element of 'dep (no - a$dep[i]- length 1)
v <- character(nrow(a))
for(i in seq_along(a$dep)) v[i] <- ifelse(a$dep[i] %in% v, "", a$dep[i])
and then remove the blank elements
v[v != ""]
#[1] "a" "b" "c" "e"
The ifelse is useful as vectorized function and its use would not be optimal here
data
a <- data.frame(dep = c('a', 'b', 'a', 'c', 'e', 'a'))

Filter vector by vector

I have vectors:
a <- c(1,2,4,5,6)
b <- c(2,4,5)
A want to extract values from 'a' which are not in 'b', so desired output is:
1,6
How could i do that?
We can use setdiff
setdiff(a, b)
#[1] 1 6
Or if there are duplicates
library(vecsets)
vsetdiff(a, b)
Or using %in% and !
a[! a %in% b]

Calculate length of each object in R

I would like to calculate the length of many objects in R and return those objects with the name-prefix 'length_'. However, when I type this code:
A <- c('A', 'B', '3')
B <- c('A', '2')
files <- ls()
for (i in 1:length(files)) assign(paste("length_",files[i], sep = ""), length(unlist(files[i])))
This returns the vectors length_A and length_B, but each with the value 1 and not 3 and 2.
Thank you for any help,
Paul
p.s. I actually would like to apply this to a different function instead of length (GC.content from package ape to calculate GC content of DNA-sequences), but with that function I have the same problem as with the abovementioned example.
In R 3.2.0, the lengths function was introduced which calculates the length of each item of a list. Using this function, as #docendo-discimus notes in the comments above, a super compact (and R-like) solution is
lengths(mget(ls()))
which returns a named vector
A B
3 2
mget returns a list of objects in the environment and is sort of like "multipleget."
A <- c('A', 'B', '3')
B <- c('A', '2')
files <- ls()
for (i in 1:length(files)) assign(paste("length_",files[i], sep = ""), length(get(files[i])))
This create a length_A of value 3 and length_B of value 2.
A <- c('A', 'B', '3')
B <- c('A', '2')
files <- list(A,B)
sapply(files,length)
this will give you the answer but I don't know if it's what you want.

index vector by value in R

Say I have two character vectors
vec <- c('A', 'B', 'C', 'D', 'E')
pat <- c('D', 'B', 'A')
how do I get the indexes of the occurrences in vec of the values in pat in the order they appear in pat?
I can try
which(vec %in% pat)
but this gives me them in the incorrect order: 1 2 4. I want them as 4 2 1.
I tried different ways to solve this problem before and always found that the easiest way to solve it is the solution as mentioned in #DavidArenburg's comment:
match(pat, vec)
# [1] 4 2 1

Resources