How to concat rows of data frame in R?

Viewed 119

I have a data frame that is consists of strings. Now I want to merge the first two rows of the data frame and set them as headers. I have a sample data frame below:

sample_data=data.frame(a=c("a ","sdf ","kjk ","oijd "),b=c("dkj ","oie ","lkd ","ohf"),c=c("sdk ","oij ","oie ","iuhi"),d=c("411 ","sdf ","iuf ","ijef"))   
> sample_data 

> sample_data
      a    b    c    d
1    a  dkj  sdk  411 
2  sdf  oie  oij  sdf 
3  kjk  lkd  oie  iuf 
4 oijd   ohf iuhi ijef

I want the output to resemble the below structure:

  a sdf  dkj oie  sdk oij  411 sdf 
1  kjk      lkd      oie      iuf 
2  oijd       ohf     iuhi     ijef

Can anyone help me with this please?

4 Answers

A base R option

setNames(
  sample_data[-(1:2), ],
  sapply(sample_data[1:2, ], paste, collapse = "")
)

which gives

  a sdf  dkj oie  sdk oij  411 sdf
3   kjk      lkd      oie      iuf 
4  oijd       ohf     iuhi     ijef

An option is to paste the first two rows, and make use of row_to_names from janitor to set the column names with the first row,

library(dplyr)
library(janitor)
library(stringr)
sample_data %>% 
 mutate(across(everything(), ~ replace(., 1, str_c(.[1:2], collapse="")))) %>% 
 row_to_names(1) %>%
  slice(-1)
   #  a sdf  dkj oie  sdk oij  411 sdf 
#1   kjk      lkd      oie      iuf 
#2  oijd       ohf     iuhi     ijef

One approach using base R would be taking the rows you want and format as names:

#Data
sample_data=data.frame(a=c("a ","sdf ","kjk ","oijd "),
                       b=c("dkj ","oie ","lkd ","ohf"),
                       c=c("sdk ","oij ","oie ","iuhi"),
                       d=c("411 ","sdf ","iuf ","ijef"),
                       stringsAsFactors = F)   
#Names
v1 <- paste0(sample_data[1,],sample_data[2,])
#Create new dataframe
ndf <- sample_data[-c(1,2),]
names(ndf) <- v1

Output:

  a sdf  dkj oie  sdk oij  411 sdf 
3   kjk      lkd      oie      iuf 
4  oijd       ohf     iuhi     ijef

Create a grouping vector g which has the same value for all rows to be pasted together and then use lapply to tapply paste with respect to g over each column. Finally convert the resulting list to a data frame.

g <- c(1, 1, 2, 3)
d <- as.data.frame(lapply(sample_data, tapply, g, paste, collapse = ""))

giving:

       a        b        c        d
1 a sdf  dkj oie  sdk oij  411 sdf 
2   kjk      lkd      oie      iuf 
3  oijd       ohf     iuhi     ijef

To set the first row as a header:

setNames(d[-1, ], d[1, ])

giving:

  a sdf  dkj oie  sdk oij  411 sdf 
2   kjk      lkd      oie      iuf 
3  oijd       ohf     iuhi     ijef

Another example

This is an example of using a different grouping vector. To set the first row as the header use the last line of code above. Here is an example of pasting together rows 1 and 2 and also pasting together rows 3 and 4. The code is the same as above except for the definition of g:

g <- c(1, 1, 2, 2)
as.data.frame(lapply(sample_data, tapply, g, paste, collapse = ""))

giving:

          a        b        c        d
1    a sdf  dkj oie  sdk oij  411 sdf 
2 kjk oijd   lkd ohf oie iuhi iuf ijef
Related