0
votes

I am trying to split a dataframe vertically after certain column. Preferably by name. The first half of the split should remain a dataframe and the second should become a matrix. Here is an example.

pp    <- rep(1:4,each=4)
cond  <- rep(c("A","B"),each=2)
time  <- rep(1:2,8)
value <- rnorm(16,1)
df <- data.frame(pp,cond,time,value)

as.data.frame(df %>%
  pivot_wider(names_from = c(time), values_from = value))


  pp cond          1           2
1  1    A  0.4121770  2.13178625
2  1    B  2.8638453 -0.64314357
3  2    A  2.2587738  1.74448028
4  2    B  0.2737670  0.89784427
5  3    A  0.5831763  2.37123498
6  3    B  0.5158274  1.40670718
7  4    A -0.6313988  1.06272354
8  4    B  2.0142500  0.01102302

Now I'd like to continue piping and split the cols pp and cond into a new dataframe and cols 1 and 2 into a matrix. Any suggestions?

1

1 Answers

0
votes

You can try this :

tidyr::pivot_wider(df, names_from = time, values_from = value) %>%
  split.default(rep(c(1, 2), each = 2)) -> data1

#change cols 1 and 2 into matrix. 
data1[[2]] <- as.matrix(data1[[2]])

data1
#$`1`
# A tibble: 8 x 2
#     pp cond 
#  <int> <chr>
#1     1 A    
#2     1 B    
#3     2 A    
#4     2 B    
#5     3 A    
#6     3 B    
#7     4 A    
#8     4 B    

#$`2`
#              1           2
#[1,]  1.4442871  1.43913039
#[2,]  2.0406232  1.48409939
#[3,]  0.7551162  1.91599206
#[4,]  1.8006224  0.06343097
#[5,] -0.4007874  1.16027754
#[6,]  0.7260376  0.01446089
#[7,]  1.0839307 -0.31999653
#[8,]  1.1612264  0.37507161

If you want data as two separate objects instead of a list using the column names. Try :

col1 <- c('pp', 'cond')
col2 <- c('1', '2')
df1 <- tidyr::pivot_wider(df, names_from = time, values_from = value)
data1 <- subset(df1, select = col1)
data2 <- subset(df1, select = col2)

Or

data1 <- df1 %>% dplyr::select(all_of(col1))
data2 <- df1 %>% dplyr::select(all_of(col2)) %>% as.matrix()