Get value of a matrix with row-index and column-index [duplicate] - r

This question already has answers here:
Index values from a matrix using row, col indices
(4 answers)
Closed 5 years ago.
I'm trying to get the value of a matrix with a vector of row indexes and column indexes like this.
M = matrix(rnorm(100),nrow=10,ncol=10)
set.seed(123)
row_index = sample(10) # 3 8 4 7 6 1 10 9 2 5
column_index = sample(10) # 10 5 6 9 1 7 8 4 3 2
Is there any way I can do something like
M[row_index, column_index]
and get the values for
M[3,10], M[8,5], ...
as a vector?

We need a cbind to create a 2 column matrix where the first column denotes row index and second column index
M[cbind(row_index, column_index)]

The solution I present is not the best way of doing things in R, because in most cases for loops are slow compared to vectorized operations. However, for the problem you can simply implement a loop to index the matrix. While there might be absolutely no reason at all to not specify any object that provide the data structure(such as a data-frame or a matrix), we can avoid it anyway using a loop construct.
for (i in 1:length(row_index)) {
print(M[row_index[i], column_index[i]])
}

Related

Convert the rows of frequency "table" (NOT matrix or dataframe) to separate lists [duplicate]

This question already has answers here:
How to convert a table to a data frame
(5 answers)
Closed last month.
I'm running frequency table of frequencies, I want to convert the table to two lists of numbers.
numbers <- c(1,2,3,4,1,2,3,1,2,3,1,2,3,4,2,3,5,1,2,3,4)
freq_of_freq <- table(table(numbers))
> freq_of_freq
1 3 5 6
1 1 1 2
From the table freq_of_freq, I'd like to get create two list, x and y, one containing the numbers 1,3,5,6 and the other with the frequency values 1,1,1,2
I tried this x <- freq_of_freq[ 1 , ] and y <- freq_of_freq[ 2 , ], but this doesn't work.
Any help greatly appreciated. Thanks
One approach is to use stack() to create a list.
numbers <- c(1,2,3,4,1,2,3,1,2,3,1,2,3,4,2,3,5,1,2,3,4)
freq_of_freq <- table(table(numbers))
stack(freq_of_freq)
#> values ind
#> 1 1 1
#> 2 1 3
#> 3 1 5
#> 4 2 6
To exactly match your expected output, you could do:
x = as.integer(names(freq_of_freq))
y = unname(freq_of_freq)
Note, the OP attempt of freq_of_freq[1, ] does not work because table returns a named integer vector for this example dataset. That is, we can't subset using matrix or data.frame notation because we only have one dimension.

Looping through items on a list in R

this may be a simple question but I'm fairly new to R.
What I want to do is to perform some kind of addition on the indexes of a list, but once I get to a maximum value it goes back to the first value in that list and start over from there.
for example:
x <-2
data <- c(0,1,2,3,4,5,6,7,8,9,10,11)
data[x]
1
data[x+12]
1
data[x+13]
3
or something functionaly equivalent. In the end i want to be able to do something like
v=6
x=8
y=9
z=12
values <- c(v,x,y,z)
data <- c(0,1,2,3,4,5,6,7,8,9,10,11)
set <- c(data[values[1]],data[values[2]], data[values[3]],data[values[4]])
set
5 7 8 11
values <- values + 8
set
1 3 4 7
I've tried some stuff with additon and substraction to the lenght of my list but it does not work well on the lower numbers.
I hope this was a clear enough explanation,
thanks in advance!
We don't need a loop here as vectors can take vectors of length >= 1 as index
data[values]
#[1] 5 7 8 11
NOTE: Both the objects are vectors and not list
If we need to reset the index
values <- values + 8
ifelse(values > length(data), values - length(data) - 1, values)
#[1] 1 3 4 7

How to create a list of numbers which are multiples of 3 and fall between a specific range? [duplicate]

This question already has answers here:
How to produce random integer numbers from 0 - 100 but by 10s only?
(2 answers)
Closed 4 years ago.
I am new to R and would appreciate any help on this 2 step task.
I need to write the R codes to create a list of numbers which are mutiples of 3 between 1 and 40.
The second part would need the codes to randomly select 6 numbers from the list above.
To generate number multiple of 3 try seq with by=3. And then use sample to pick 6 random samples out of that sequence. I have used set.seed(1) to get fixed output:
set.seed(1)
sample(seq(3,40,by=3), 6)
#[1] 12 15 21 30 6 24
Here is a solution in a step-by-step manner:
# 1. List of numbers between 1 and 40
list_numbers <- seq(1:40)
# 2. Filter
list_filter <- sapply(list_numbers, function(x) {x %% 3 == 0})
# 3. List of numbers multiple 3
list_numbers_multiple_3 <- list_numbers[list_filter]
# 4. Select 6 random numbers
sample(list_numbers_multiple_3, 6)

R if function over two columns of different length [duplicate]

This question already has answers here:
How to join (merge) data frames (inner, outer, left, right)
(13 answers)
Closed 6 years ago.
I am new to R and programming in general. I have two data frames from which I want to calculate the Win probability from the counts of two different data frames Wins and Losses. I want to check through the list and check whether the values for the score appear in both lists, if they do, I want to perform and operation, if they do not I would like it just to return an NA.
df W df L
score freq score freq
5 10 5 10
10 10 10 5
7 2 3 2
4 1
Here is my function I have written so far:
test <- function(W, L){
if (W$score == L$score) {
total <- W$freq + L$freq
W$freq / total
}
else NA
}
I want the output to be a list of the length of W:
0.5
0.66
NA
NA
This works fine for the first value in the data frame but I get the following error: the condition has length > 1 and only the first element will be used. I have been reading here on StackOverflow that I should use an ifelse function instead as that will loop through all of the rows. However, when I tried this it then had a problem with the two data frame columns being of different lengths. I want to re-use this function over a lot of different data frames and they will always be of different lengths, so I would like a solution for that.
Any help would be much appreciated and I can further clarify myself if it is currently unclear.
Thanks
You need to join these two data frames using merge function like this:
W <- data.frame(score=c(1,2,3), freq=c(5,10,15))
L <- data.frame(score=c(1,2,4), freq=c(2,4,8))
merge(W, L, by=c("score"="score"), all=TRUE)
score freq.x freq.y
1 1 5 2
2 2 10 4
3 3 15 NA
4 4 NA 8
Parameter all set to TRUE means that you want to get all the results from both data frames.

How to split data.frame into smaller data.frames of predetermined number of rows? [duplicate]

This question already has answers here:
The difference between bracket [ ] and double bracket [[ ]] for accessing the elements of a list or dataframe
(11 answers)
Closed 7 years ago.
I have the following data frame:
df <- data.frame(a=rep(1:3),b=rep(1:3),c=rep(4:6),d=rep(4:6))
df
a b c d
1 1 1 4 4
2 2 2 5 5
3 3 3 6 6
i would like to have a vector N which determines my window size so for thsi example i will set
N <- 1
I would like to split this dataframe into equal portions of N rows and store the 3 resulting dataframes into a list.
I have the following code:
groupMaker <- function(x, y) 0:(x-1) %/% y
testlist2 <- split(df, groupMaker(nrow(df), N))
The problem is that this code renames my column names by adding an X0. in front
result <- as.data.frame(testlist2[1])
result
X0.a X0.b X0.c X0.d
1 1 1 4 4
>
I would like a code that does the exact same thing but keeps the column names as they are. please keep in mind that my original data has a lot more than 3 rows so i need something that is applicable to a much larger dataframe.
To extract a list element, we can use [[. Also, as each list elements are data.frames, we don't need to explicitly call as.data.frame again.
testlist2[[1]]
We can also use gl to create the grouping variable.
split(df, as.numeric(gl(nrow(df), N, nrow(df))))

Resources