4

I have a data frame and I would like to 'align' each column so that the maximum value for each column is on the same row.

I was trying to do this using base functionality, but am getting the wrong results, ie. just overwriting and not shifting. I just found the Lag function in Hmisc, however, I am sure there is a way to do this in base and I"m just thinking about it wrong. I would prefer this, as when I try to run this later on another computer with a different verison of R there are always some package that aren't supported.

Thanks for any help,

maxIndices<-apply(df,2,function(x){ maxInt<-max(x,na.rm=T) maxInt_indx<-which(x==maxInt) }) maxMaxIndex<-max(maxIndices) minMaxIndex<-min(maxIndices) ## apply(df,2,function(x){ maxInt<-max(x,na.rm=T) maxInt_indx<-which(x==maxInt) shift<-maxMaxIndex-maxInt_indx shifted_vec<-c(rep(NA,times=shift), x[1:length(x)+shift]) ## this is producing the wrong results # shifted_vec<-Lag(x,shift) # is there a way to do this using just base functionality }) 
3
  • It should be one line, but to make sure your answer is correct, can you post some sample data and output? Commented Nov 18, 2014 at 15:16
  • @beginneR Your code doesn't work that way; try it. Commented Nov 18, 2014 at 15:43
  • @nograpes - you're right. Once again I confused dplyr::lag with stats::lag Commented Nov 18, 2014 at 15:48

4 Answers 4

10

My interpretation of what a shift function implementation might / should look like:

#' function that shifts vector values to right or left #' #' @param x Vector for which to shift values #' @param n Number of places to be shifted. #' Positive numbers will shift to the right by default. #' Negative numbers will shift to the left by default. #' The direction can be inverted by the invert parameter. #' @param invert Whether or not the default shift directions #' should be inverted. #' @param default The value that should be inserted by default. shift <- function(x, n, invert=FALSE, default=NA){ stopifnot(length(x)>=n) if(n==0){ return(x) } n <- ifelse(invert, n*(-1), n) if(n<0){ n <- abs(n) forward=FALSE }else{ forward=TRUE } if(forward){ return(c(rep(default, n), x[seq_len(length(x)-n)])) } if(!forward){ return(c(x[seq_len(length(x)-n)+n], rep(default, n))) } } 

Example Usage

shift(1:10, 5) ## [1] NA NA NA NA NA 1 2 3 4 5 shift(1:10, -5, default = 999) ## [1] 6 7 8 9 10 999 999 999 999 999 
Sign up to request clarification or add additional context in comments.

Comments

2

I think you just have a typo in one line:

 shifted_vec<-c(rep(NA,times=shift), x[1:(length(x)-shift)]) ## this is producing the wrong results 

Notice the (length(x)-shift). The + should be a - and there should be brackets around it.


Although a more concise version of your code would be:

max.ind <- sapply(df, which.max) diff <- max(max.ind) - max.ind shift <- function (x, shift) c(rep(NA,times=shift), x[1:(length(x)-shift)]) mapply(shift, df, diff) 

1 Comment

base::lag returns a time-series object, which isn't what I want here.
2

You might like Lag from Hmisc. "Lag" - not "lag".

library(Hmisc) Lag(1:10,3) [1] NA NA NA 1 2 3 4 5 6 7 

Comments

1

If you're using tidyverse, you have dplyr lag/lead:

dplyr::lag(1:5) #> [1] NA 1 2 3 4 dplyr::lead(1:5) #> [1] 2 3 4 5 NA 

You can define the padding value with argument default.

Importing tidyverse or dplyr will mask base R's stats::lag.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.