Home > Back-end >  Moving data-frame columns as per defined extent
Moving data-frame columns as per defined extent

Time:02-10

As shown below, let's assume we have a data frame with 1 'extent' column, and 10 'col' columns, of which only first 7 'cols' are filled in the beginning.

Note: Grey highlight in NA cells is just for aesthetics.

enter image description here

We need to move first 'extent' cells of col columns to the end by some vectorised formula or a function. The output should look like below:

enter image description here

I wrote following piece of code to do it, but it's not working:

df <- ifelse(df$extent > 0,
                  df[, c(1, 9:(9 df$extent), 2 df$extent:8,2:(1 df$extent),(9 df$extent):11)
                      ] ,df)

I get the error as: "numerical expression has 3 elements: only the first used"

Please help me out.

CodePudding user response:

Using a for loop and a swap function :

dat <- structure(list(extent = 0:2, col1 = c("1", "A", "a"), col2 = c("2", "B", "b"), col3 = c("3", "C", "c"), col4 = c("4", "D", "d"), col5 = c("5", "E", "e"), col6 = c("6", "F", "f"), col7 = c("7", "G", "g"), col8 = c(NA, NA, NA), col9 = c(NA, NA, NA), col10 = c(NA, NA, NA)), row.names = c(NA, -3L), class = "data.frame")

for (i in 1:nrow(dat)) {
  k <- 7 #number of non NA cols
  ext <- dat$extent[i]
  if(ext > 0) seqinr::swap(dat[i, 2:(ext   1)], dat[i, (k   2):(k   ext   1)])
}

dat

CodePudding user response:

Inefficient, but a start:

myshift <- function(x, n = 1) { if (!length(x) || n == 0) return(x); x[(seq_along(x) - n - 1) %% length(x)   1]; }
dat[-1] <- do.call(rbind, Map(function(z, n) myshift(z, n), asplit(as.matrix(dat[-1]), 1), dat$extent))
dat
#   extent   V1   V2 V3 V4 V5 V6 V7   V8   V9  V10
# 1      0    1    2  3  4  5  6  7 <NA> <NA> <NA>
# 2      1 <NA>    A  B  C  D  E  F    G <NA> <NA>
# 3      2 <NA> <NA>  a  b  c  d  e    f    g <NA>

Data

dat <- structure(list(extent = 0:2, V1 = c("1", "A", "a"), V2 = c("2", "B", "b"), V3 = c("3", "C", "c"), V4 = c("4", "D", "d"), V5 = c("5", "E", "e"), V6 = c("6", "F", "f"), V7 = c("7", "G", "g"), V8 = c(NA, NA, NA), V9 = c(NA, NA, NA), V10 = c(NA, NA, NA)), row.names = c(NA, -3L), class = "data.frame")
  • Related