R - cannot select the desired element in a vector [duplicate] - r

This question already has an answer here:
How to index an element of a list object in R
(1 answer)
Closed 8 years ago.
I have a vector of data called empl which I extracted from a NetLogo model using RNetLogo and whose entries look like
[[1403]]
[1] 99
[[1404]]
[1] 97
[[1405]]
[1] 95
[[1406]]
[1] 95
[[1407]]
[1] 95
[[1408]]
[1] 97
I would like to perform simple operation on the last numbers of the vector's entries (the 95,97,...).
Now if I write something like
empl[731] + empl[890]
I get
Error in empl[i] + empl[j] : non-numeric argument to binary operator
If I understand correctly, this is due the fact that empl[i] does not pick the last number in the corresponding entry but rather the whole entry for instance
[[1408]]
[1] 97
But I haven't been able to figure out how to get the last number only. I tried
empl[1,i]
and
empl[i,1]
but got
Error in empl[1, i] : incorrect number of dimensions
Any help on how to select the last number only would be much appreciated. If someone can emply understand the structure of the vector empl that would be even better.

Your empl object is not a vector. It is a list. A list object is formed by elements which can be arbitrary R objects. When you print a list and see:
[[1403]]
[1] 99
it means that the 1403rd element of this list is a vector with just one value (99). You select an element of a list through the double square bracket ([[) operator. So, if you try:
empl[[731]] + empl[[890]]
you won't receive any error. I suggest to read the R language definition, and in particular sections 2.1 (which describes object types) and 3.4 (when indexing is discussed).

It seems like empl is a list
You could do
Reduce(`+`,tail(empl,2))
to get the sum of last 2 elements
If you need to sum some specific elements for example 731, 752, 834
Reduce(`+`,empl[c(731, 752, 834)])
#[1] 812
Or
sum(unlist(tail(empl,2)), na.rm=TRUE)
data
set.seed(42)
empl <- replicate(1000,list(sample(1:950,1,replace=TRUE)))

Related

How to find the length of a list based on a condition in R

The problem
I would like to find a length of a list.
The expected output
I would like to find the length based on a condition.
Example
Suppose that I have a list of 4 elements as follows:
myve <–list(1,2,3,0)
Here I have 4 elements, one of them is zero. How can I find the length by extracting the zero values? Then, if the length is > 1I would like to substruct one. That is:
If the length is 4 then, I would like to have 4-1=3. So, the output should be 3.
Note
Please note that I am working with a problem where the zero values may be changed from one case to another. For example, For the first list may I have only one 0 value, while for the second list may I have 2 or 3 zero values.
The values are always positive or zero.
You just need to apply the condition to each element. This will produce a list of boolean, then you sum it to get the number of True elements (i.e. validation your condition).
In your case:
sum(myve != 0)
In a more complex case, where the confition is expressed by a function f:
sapply(myve, f)
Use sapply to extract the ones different to zeros and sum to count them
sum(sapply(myve, function(x) x!=0))

Storing a value in a nested list with an unknown depth in R

I am trying to optimize a code which is very computational-intensive, because it deals with subsets of a 80-elements set.
A crucial step that I want to accelerate is finding if the current subset in my loop has already been treated or not. For the moment, I check if this subset is contained in the already treated subset of the same size k (cardinal). It would be much more faster to store progressively treated subset in a nested list to check if a subset has already been treated or not (O(1) instead of a search in O(80 choose k)).
I had no problem coding a function to check if the current subset is in my nested list of treated subset: access(treated, subset=c(2,5,3)) returns TRUE iff treated[[2]][[5]][[3]]==TRUE
However, I have no idea how to store (inside my loop) my current subset in the list of treated. I would like something like this to be possible: treated[h] <- TRUE where h is my current subset (in the above example: h=c(2,5,3))
The main problem that I am facing is that the number of "[[..]]" varies inside my loop. Do I have any other option rather than completing h so that it has a length of 80 and putting a sequence of 80 "[[..]]", like: treated[[h[1]]][[h[2]]]...[[h[80]]] <- TRUE ?
If h is a vector of values then
"[["(treated, h)
recursively subsets the list items.
For example, I created a (not so highly) nested list:
> a
[[1]]
[[1]][[1]]
[1] 2
[[1]][[2]]
[[1]][[2]][[1]]
[1] 3
[[2]]
[1] 1
The following command, correctly recursively applies item subsetting to the list:
> "[["(a, c(1,2,1))
[1] 3
The length of the recursively subsetting vector can vary without fixing the number of [[..]]'s. For example, subsetting two levels of depth with the same syntax:
> "[["(a, c(1,2))
[[1]]
[1] 3

How to get an Element from a vector without using numbers or indices?

Lets say I have these two vectors in my R workspace with the following content:
[1] "Atom.Type" and "Molar.Mass"
> Atom.Type
[1] "Oxygen" "Lithium" "Nitrogen" "Hydrogen"
> Molar.Mass
[1] 16 6.9 14 1
I now want to assign the Molar.Mass belonging to "Lithium" (i.e. 6.9) to a new variable called mass.
The problem is: I have to do that without using any numbers or indices.
Does anyone have a suggestion for this problem?
This should work: mass<-Molar.Mass[Atom.Type=="Lithium"] Clearly this assumes the two vectors are of the same length and sorted correctly. See additional comment from Roland below.

R commands for finding mode in R seem to be wrong

I watched video on YouTube re finding mode in R from list of numerics. When I enter commands they do not work. R does not even give an error message. The vector is
X <- c(1,2,2,2,3,4,5,6,7,8,9)
Then instructor says use
temp <- table(as.vector(x))
to basically sort all unique values in list. R should give me from this command 1,2,3,4,5,6,7,8,9 but nothing happens except when the instructor does it this list is given. Then he says to use command,
names(temp)[temp--max(temp)]
which basically should give me this: 1,3,1,1,1,1,1,1,1 where 3 shows that the mode is 2 because it is repeated 3 times in list. I would like to stay with these commands as far as is possible as the instructor explains them in detail. Am I doing a typo or something?
You're kind of confused.
X <- c(1,2,2,2,3,4,5,6,7,8,9) ## define vector
temp <- table(as.vector(X))
to basically sort all unique values in list.
That's not exactly what this command does (sort(unique(X)) would give a sorted vector of the unique values; note that in R, lists and vectors are different kinds of objects, it's best not to use the words interchangeably). What table() does is to count the number of instances of each unique value (in sorted order); also, as.vector() is redundant.
R should give me from this command 1,2,3,4,5,6,7,8,9 but nothing happens except when the instructor does it this list is given.
If you assign results to a variable, R doesn't print anything. If you want to see the value of a variable, type the variable's name by itself:
temp
you should see
1 2 3 4 5 6 7 8 9
1 3 1 1 1 1 1 1 1
the first row is the labels (unique values), the second is the counts.
Then he says to use command, names(temp)[temp--max(temp)] which basically should give me this: 1,3,1,1,1,1,1,1,1 where 3 shows that the mode is 2 because it is repeated 3 times in list.
No. You already have the sequence of counts stored in temp. You should have typed
names(temp)[temp==max(temp)]
(note =, not -) which should print
[1] "2"
i.e., this is the mode. The logic here is that temp==max(temp) gives you a logical vector (a vector of TRUE and FALSE values) that's only TRUE for the elements of temp that are equal to the maximum value; names(temp)[temp==max(temp)] selects the elements of the names vector (the first row shown in the printout of temp above) that correspond to TRUE values ...

How to get a value of a multi-dimensional array by an INCOMPLETE vector of indices

This question is very similar to
R - how to get a value of a multi-dimensional array by a vector of indices
I have:
dim_count <- 5
dims <- rep(3, dim_count)
pi <- array(1:3^5, dims)
I want to get an entire line, but with an automatic building of the address of this line.
For example, I would like to get:
pi[1,,2,2,3]
## [1] 199 202 205
You could insert a sequence covering the whole dimension in the appropriate slot:
do.call("[",list(pi,1,1:dim(pi)[2],2,2,3))
By the way, defining a variable called pi is a little dangerous (I know this was inherited from the previous question) -- suppose you tried a few lines later to compute the circumference of a circle as pi*diameter ...

Resources