简体   繁体   中英

Split dataframe on filtered character and make multiple new columns

I have aa data preprocessing issue that is very common in my work. I usually have two files which I in the end want to do a large matching operation for. It´s usually a two step process where the first step involves making a "cleaned" dataframe of the first file and the second step is to make a match(vlookup) with the second file of a larger dataframe. I need help with the first step in this question. I have created a simple example below to work on. My simplified dataframe:

c1 <- 1:15
c2 <- c("Valuelabels", "V1", "1", "2", "Valuelabels", "V2", "1", "2", "3", "Valuelabels", "V3", "1", "2", "3", "4")
c3 <- c("", "", "Male", "Female", "", "", "Married", "Single", "Other", "", "", "SingleWithChildren", "SingleWithoutChildren","MarriedWithChildren", "PartneredWithChildren") 

df <- data.frame(row.names =c1,c2,c3)
df

            c2                    c3
1  Valuelabels                      
2           V1                      
3            1                  Male
4            2                Female
5  Valuelabels                      
6           V2                     
7            1               Married
8            2                Single
9            3                 Other
10 Valuelabels                      
11          V3                      
12           1    SingleWithChildren
13           2 SingleWithoutChildren
14           3   MarriedWithChildren
15           4 PartneredWithChildren

Now, I would like to split the dataframe on the "Valuelabel" string in the first column and end up with a new dataframe looking like this :

   V1 V1_match V2 V2_match V3              V3_match
1:  1     Male  1  Married  1    SingleWithChildren
2:  2   Female  2   Single  2 SingleWithoutChildren
3: NA           3    Other  3   MarriedWithChildren
4: NA          NA           4 PartneredWithChildren

I would in the end like to create a dataframe with the V1 as column names and the matching values under those as a new column beside named in my example V1_match... and so on for V2 to V3.

This dataframe will conclude my step one before matching it to a larger dataframe.

Very greateful for help.

Here's a possible data.table solution

library(data.table) # v 1.9.5
setDT(df)[, indx := c2[2L], by = cumsum(c2 == "Valuelabels")]
df2 <- df[!grepl("\\D", c2)][, indx2 := seq_len(.N), by = indx]
dcast(df2, indx2 ~ indx, value.var = c("c2", "c3"))
#    indx2 V1_c2 V2_c2 V3_c2  V1_c3   V2_c3                 V3_c3
# 1:     1     1     1     1   Male Married    SingleWithChildren
# 2:     2     2     2     2 Female  Single SingleWithoutChildren
# 3:     3    NA     3     3     NA   Other   MarriedWithChildren
# 4:     4    NA    NA     4     NA      NA PartneredWithChildren

You''ll need to install data.table v > 1.9.5 in order to run this using

library(devtools)
install_github("Rdatatable/data.table", build_vignettes = FALSE)

An alternative approach base R :

lst = lapply(split(df,cumsum(df$c2=='Valuelabels')), tail, -2)
Reduce(function(u,v) merge(u,v,by='c2',all=T), lst)
#  c2   c3.x    c3.y                    c3
#1  1   Male Married    SingleWithChildren
#2  2 Female  Single SingleWithoutChildren
#3  3   <NA>   Other   MarriedWithChildren
#4  4   <NA>    <NA> PartneredWithChildren

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM