Reputation: 677
I have a dataframe that looks like this:
a <- as.data.frame(t(matrix(c('gr1','','','','gr2','','','','','gr3','','',
rep(1,12),rep(2,12)),ncol=3)))
a
looks like:
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
gr1 gr2 gr3
1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2
Columns V1-V4 belong to gr1, V5-V9 to gr2, and V10-V12 to gr3.
I would like to separate these groups (gr1-gr3) and their corresponding columns and put them all in a list that I can later on loop and do some analysis. So the desired output is:
list1 = (gr1,gr2,gr3)
, where each of gr1, gr2, and gr3 are a dataframe with their corresponding columns.
Upvotes: 2
Views: 66
Reputation: 886938
We create a grouping variable based on whether the first row element is blank (''
) or not. Then, split
the column names of 'a' with the 'grp' to a list
and then subset
the columns and rows (remove the first row) using lapply
, change the names
of the 'lst' as the 'gr' values that we extract the first row of 'a'.
grp <- cumsum(as.character(unlist(a[1,]))!='')
lst <- lapply(split(names(a), grp), function(nm) a[-1, nm])
nm1 <- as.character(unlist(a[1,]))
names(lst) <- nm1[nzchar(nm1)]
NOTE: The columns in 'a' are factor
class due to the presence of the second header ('gr') as the first row. If we need to convert the columns in each data.frame in the 'lst' to numeric,
lapply(lst, function(x) {
x[] <- lapply(x, function(.x) as.numeric(as.character(.x)))
x})
Upvotes: 2