Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split data frame by column names in R?

My 24 hours of search for what I feel is a trivial (Not for a newbie in R as I am) problem has not yet born fruits. So please help me out. I have a single data frame that I would wish to split into two. Here is how the data looks like;

d1 d2 d3 d4 p1 p2 p3 p4
30 40 20 60 1  3  2  5  
20 50 40 30 3  4  1  5 
40 20 50 30 2  3  1  4 

here is what I want it to look like;

$d
d1 d2 d3 d4
30 40 20 60
20 50 40 30
40 20 50 30 

$p
p1 p2 p3 p4
1  3  2  5 
3  4  1  5
2  3  1  4

I have tried to most of the commands and examples online but they all seem to be splitting data along rows such as in:

split(1:3, 1:2)

How can I indicate even with the use of indexes that I want to split the first 4 columns from the last four?

like image 248
George Kariuki Avatar asked Jul 12 '18 03:07

George Kariuki


2 Answers

Using sapply and startsWith:

sapply(c("d", "p"),
       function(x) df[startsWith(names(df),x)],
       simplify = FALSE)

# $d
# d1 d2 d3 d4
# 1 30 40 20 60
# 2 20 50 40 30
# 3 40 20 50 30
# 
# $p
# p1 p2 p3 p4
# 1  1  3  2  5
# 2  3  4  1  5
# 3  2  3  1  4

A tidyverse translation:

library(tidyverse)
map(set_names(c("d", "p")),~select(df,starts_with(.x)))
# $d
# d1 d2 d3 d4
# 1 30 40 20 60
# 2 20 50 40 30
# 3 40 20 50 30
# 
# $p
# p1 p2 p3 p4
# 1  1  3  2  5
# 2  3  4  1  5
# 3  2  3  1  4
like image 50
Moody_Mudskipper Avatar answered Oct 25 '22 03:10

Moody_Mudskipper


Here is an option with split from base R

split.default(df1, sub('\\d+', '', names(df1)))
#$d
#  d1 d2 d3 d4
#1 30 40 20 60
#2 20 50 40 30
#3 40 20 50 30

#$p
#  p1 p2 p3 p4
#1  1  3  2  5
#2  3  4  1  5
#3  2  3  1  4

data

df1 <- structure(list(d1 = c(30L, 20L, 40L), d2 = c(40L, 50L, 20L), 
    d3 = c(20L, 40L, 50L), d4 = c(60L, 30L, 30L), p1 = c(1L, 
    3L, 2L), p2 = c(3L, 4L, 3L), p3 = c(2L, 1L, 1L), p4 = c(5L, 
    5L, 4L)), class = "data.frame", row.names = c(NA, -3L))
like image 33
akrun Avatar answered Oct 25 '22 04:10

akrun