R - automatically add each n-th column of the data frame and save them as new objects

I have a date frame called DF with, say, three variables that repeat each other cyclically:

      A      B      C      A      B      C 
1    a1     b1     c1     a5     b5     c5
2    a2     b2     c2     a6     b6     c6
3    a3     b3     c3     a7     b7     c7
4    a4     b4     c4     a8     b8     c8

I want to stack the first column A in the second column A (and on the third, fourth and so on, if they exist), and do the same with other variables, and then save the result as new objects (as vectors, for example ) So I want to get

V_A <- c(a1,a2,a3,a4,a5,a6,a7,a8)
V_B <- c(b1,b2,b3,b4,b5,b6,b7,b8)
V_C <- c(c1,c2,c3,c4,c5,c6,c7,c8)

So far it’s very easy to do manually, for example

V_A <- DF[,seq(1, ncol(DF), 3]
V_A <- stack(DF)
V_B <- DF[,seq(2, ncol(DF), 3]
V_B <- stack(DF)
V_C <- DF[,seq(3, ncol(DF), 3]
V_C <- stack(DF)

, , - , , ad-hoc- . , : 1) n- 2) 3)

, , . .

, , , , . :

     A1      B1      C1      A2      B2      C2 
1    a11     b11     c11     a25     b25     c25
2    a12     b12     c12     a26     b26     c26
3    a13     b13     c13     a27     b27     c27
4    a14     b14     c14     a28     b28     c28

:

V_A <- c(a11,a12,a13,a14,a25,a26,a27,a28)
V_B <- c(b11,b12,b13,b14,b25,b26,b27,b28)
V_C <- c(c11,c12,c13,c14,c25,c26,c27,c28)

?

+4
3

. .

1) aperm 3d- a, m, . , . (2) (3) .

k <- 3
nr <- nrow(DF)
nc <- ncol(DF)
unames <- unique(names(DF))

a <- array(as.matrix(DF), c(nr, k, nc/k))
m <- matrix(aperm(a, c(1, 3, 2)),, k, dimnames = list(NULL, unames))
as.data.frame(m, stringsAsFactors = FALSE)

:

   A  B  C
1 a1 b1 c1
2 a2 b2 c2
3 a3 b3 c3
4 a4 b4 c4
5 a5 b5 c5
6 a6 b6 c6
7 a7 b7 c7
8 a8 b8 c8

, EDIT, unames : DF2 - DF :

unames <- unique(sub("\\d*$", "", names(DF2)))

2) lapply . unames :

L <- lapply(split(as.list(DF), names(DF)), unlist)
as.data.frame(L, stringsAsFactors = FALSE)

:

   A  B  C
1 a1 b1 c1
2 a2 b2 c2
3 a3 b3 c3
4 a4 b4 c4
5 a5 b5 c5
6 a6 b6 c6
7 a7 b7 c7
8 a8 b8 c8

, EDIT, , DF2 .

names0 <- sub("\\d*$", "", names(DF2))   # names without the trailing digits
L <- lapply(split(as.list(DF2), names0), unlist)
as.data.frame(L, stringsAsFactors = FALSE)

3) nc unames . varying - k, , i- c(i, i+k, ...). , reshape , setNames(DF, 1:nc) . time id, .

varying <- split(1:nc, names(DF))
reshape(setNames(DF, 1:nc), dir = "long", varying = varying, v.names = unames)

:

    time  A  B  C id
1.1    1 a1 b1 c1  1
2.1    1 a2 b2 c2  2
3.1    1 a3 b3 c3  3
4.1    1 a4 b4 c4  4
1.2    2 a5 b5 c5  1
2.2    2 a6 b6 c6  2
3.2    2 a7 b7 c7  3
4.2    2 a8 b8 c8  4

, EDIT, . setNames(DF, 1:nc), . , varying=TRUE ( . @thelatemail) varying. DF2 , names0 (2).

reshape(DF2, dir = "long", varying = TRUE, v.names = unique(names0))

:

Lines <- "      A      B      C      A      B      C 
1    a1     b1     c1     a5     b5     c5
2    a2     b2     c2     a6     b6     c6
3    a3     b3     c3     a7     b7     c7
4    a4     b4     c4     a8     b8     c8"
DF <- read.table(text = Lines, as.is = TRUE, check.names = FALSE)

DF2 <- setNames(DF, c("A1", "B1", "C1", "A2", "B2", "C2")) # test input

Upate: . DF2 , , . ( , DF2 DF, .)

+4

stack unstack

NEWDF=stack(DF)
NEWDF$ind=as.character(NEWDF$ind)
NEWDF$ind=rep(NEWDF$ind[1:(dim(NEWDF)[1]/2)],2)
unstack(NEWDF)
   A  B  C
1 a1 b1 c1
2 a2 b2 c2
3 a3 b3 c3
4 a4 b4 c4
5 a5 b5 c5
6 a6 b6 c6
7 a7 b7 c7
8 a8 b8 c8
+1

This gives you the nth columns stacked in shared data.frames stored in a list:

library(tidyr)
cols <- ncol(dat)
set_width <- 3
result <- dat %>%
  gather(key, value) %>%
  split(., rep(rep(1:set_width, each = nrow(dat)), ncol(dat)/set_width))

Data:

dat <- read.table(text = "      A      B      C      A      B      C 
1    a1     b1     c1     a5     b5     c5
                  2    a2     b2     c2     a6     b6     c6
                  3    a3     b3     c3     a7     b7     c7
                  4    a4     b4     c4     a8     b8     c8", check.names = TRUE)

(If variable names are not unique, that is, they exactly repeat, insert janitor::clean_names()into the pipeline).

0
source

Source: https://habr.com/ru/post/1687842/


All Articles