Working with sums in R - r

How does one work with sums in R? I can't seem to find an easy way to calculate sums \sum_{i=m}^n a_i. There are three things to decide here; where summation starts, where it ends, and what elements are to be summed.
I have a data frame df and I would like to calculate sum_{i=1}^{n-3} df$col[i]*df$col[i+3], col being a column of length 1000 in df, i.e. n=1000... How can I do this? I've found one very cumbersome way of doing it, namely
new = NULL
for (n in 1:997)
{ new = df$col[n]*df$col[n+3] }
sum(new)
That's a stupid way of doing it, so how do it in a more "natural" way? Yes, I'm sure this precise question has been asked but I didn't know how to narrow down my searches. "R+sum+why dont programmers think like mathematicians", maybe ;) Anyway, hints or links to tutorials for R beginners would be much appreciated, thanks.

You can do this with:
sum(df$col[1:997] * df$col[4:1000])
This will be a good deal quicker than looping through the indices and individually multiplying.

You should rather use vectorization and some tricks to avoid indexes:
with(df, sum(head(col,-3)*tail(col,-3)))

Or use the lead function:
sum(df$col * lead(df$col, 3, default = 0))

Related

Convert from matrix to list matrix

Sorry for the noob question but I can't seem to get this to work!
X=cbind(rep(1,m), h2(x), h3(x)) #obs
So I have a 17*3 matrix X I have to create a matrix(list(),17,3) version of this matrix. I did manually below so you can see the desired result, but there must be an easier way to do this?
Z=matrix(list(X[1,1],X[2,1],X[3,1],X[4,1],X[5,1],X[6,1],X[7,1],X[8,1],X[9,1],X[10,1],X[11,1],X[12,1],X[13,1],X[14,1],X[15,1],X[16,1],X[17,1],X[1,2],X[2,2],X[3,2],X[4,2],X[5,2],X[6,2],X[7,2],X[8,2],X[9,2],X[10,2],X[11,2],X[12,2],X[13,2],X[14,2],X[15,2],X[16,2],X[17,2],X[1,3],X[2,3],X[3,3],X[4,3],X[5,3],X[6,3],X[7,3],X[8,3],X[9,3],X[10,3],X[11,3],X[12,3],X[13,3],X[14,3],X[15,3],X[16,3],X[17,3]),17,3)
I tried this (amongst others)
Z2=list(X[1:17,1],X[1:17,2],X[1:17,3])
Z3=matrix(Z2[1:3],17,3)
But it doesn't give the correct results! It just repeats the three column vectors over and over.
Can someone please explain how to do this correctly.
Apparently you want Z <- matrix(as.list(X), ncol = 3). However, I don't see how this structure could be useful.

Use values from 2 matrices to index a third in R

I'm optimizing a more complex code, but got stuck with this problem.
a<-array(sample(c(1:10),100,replace=TRUE),c(10,10))
m<-array(sample(c(1:10),100,replace=TRUE),c(10,10))
f<-array(sample(c(1:10),100,replace=TRUE),c(10,10))
g<-array(NA,c(10,10))
I need to use the values in a & m to index f and assign the value from f to g
i.e. g[1,1]<-f[a[1,1],m[1,1]] except for all the indexes, and as optimally/fast as possible
I could obviously make a for loop to do this for me but that seems rather dumb and slow. It seems like I should be able to us something in the apply family, but I've had no luck with figuring out how to do that. I do need to keep the data structured as it is here so that I can use matrix operations in different parts of my code. I've been searching for an answer to this but haven't found anything particularly helpful yet.
g[] <- f[cbind(c(a), c(m))]
This takes advantage of the fact that matrices can be addressed as vectors and using a matrix as the index.

Accessing and changing list element attributes

The background to this is that I'm mostly a Python programmer who has some passing familiarity with R. I've been tasked to look at an R script that was written by a Perl programmer who used for and while loops a lot, to see if I can make it more R-like and get it to run faster.
For example purposes, I have the following list:
> lnums <- list(1:5, 6:7, 8:12)
For the elements that have a length less than 5 (lnums[[2]]), I want to change the length to be 5. The original code uses a for loop to tack NA values to the end of any shorter vectors, and I know that there's got to be a better way than that. I was playing around with ways to get to it and came up with
> sapply(lnums, FUN=function(x) length(x) < 5)
which gets the right element, but I'm unable to figure out how to incorporate this into the subscript of a length(lnums[]) <- 5 statement. I know this is probably a really novice question, but I'd appreciate any help I can get.
Additionally, the reason that I want to increase the length of the shorter list elements is so that I can put the list into a data frame. It would be great if there was a way to do that without messing around with lengths, although I still wouldn't mind an answer to my first question to satisfy my curiosity if nothing else.
Thanks all. I've been digging through some topics in here and you've already helped me out quite a bit!
Here's one way:
lapply(lnums, 'length<-', 5)

R or MATLAB: permute a large sparse matrix into a block diagonal matrix

I have a large sparse matrix, and I want to permute its rows or columns to turn the original matrix into a block diagonal matrix. Anyone knows which functions in R or MATLAB can do this? Thanks a lot.
I'm not really set up to test this, but for a matrix m I would try:
p = symrcm(m);
block_m = m(p,p);
If that doesn't work, look through the other functions listed in help sparfun to see if any will help you out.
The seriation package in R has a number of tools for problems related to this one.
Not exactly sure if this is what you want, but in MATLAB this is what I have used in the past. Probably not the most elegant solution.
I go from sparse to full and then chop the thing into square blocks.
A=full(A);
Then:
blockedmatrix = mat2cell(A, (n*ones(1,size(A,1)/n)), ...
(n*ones(1,size(A,1)/n))); %found somewhere on internetz
This returns a cell, where each entry is of size nxn.
It's easy to extract the blocks of interest, manipulate them, and then restore them to a matrix with cell2mat.
Maybe a bit late to the game, but since there are available commands, here is a simple one. If you have a matrix H and the block diagonal form is needed, you can obtain it through the following lines (MATLAB):
[p,q] = dmperm(H);
H(p,q)
which is equivalent to Dulmage - Mendelsohn permutation.

Cumulative sum for n rows

I have been trying to produce a command in R that allows me to produce a new vector where each row is the sum of 25 rows from a previous vector.
I've tried making a function to do this, this allows me to produce a result for one data point.
I shall put where I haver got to; I realise this is probably a fairly basic question but it is one I have been struggling with... any help would be greatly appreciated;
example<-c(1;200)
fun.1<-function(x)
{sum(x[1:25])}
checklist<-sapply(check,FUN=fun.1)
This then supplies me with a vector of length 200 where all values are NA.
Can anybody help at all?
Your example is a bit noisy (e.g., c(1;200) has no meaning, probably you want 1:200 there, or, if you would like to have a list of lists then something like rep, there is no check variable, it should have been example, etc.).
Here's the code what I think you need probably (as far as I was able to understand it):
x <- rep(list(1:200), 5)
f <- function(y) {y[1:20]}
sapply(x, f)
Next time please be more specific, try out the code you post as an example before submitting a question.

Resources