简体   繁体   中英

Convert Rows into Columns by matching string in R

I have number of rows in a list like '

[1,]  "Home"
[2,]  "A"
[3,]  "B"
[4,]  "C"
[5,]  "Home"
[6,]  "D"
[7,]  "E"
[8,]  "Home"
[9,]  "F"
[10,] "G"
[11,] "H"
[12,] "I"

these rows are coming dynamically...after "Home" there can be two,three,four,five or more subcategories....so binding is not working... I have more than 5000 rows and "Home" is common in the start for every subcategories..

I Want it to look like this.

       [,1]   [,2] [,3] [,4] [,5]

[1,]  "Home"  "A"  "B"  "C"   
[2,]  "Home"  "D"  "E"
[3,]  "Home"  "F"  "G"  "H"  "I"

OR

I have also used transpose to covert all rows into columns and on using transpose I got.

   [,1]    [,2] [,3] [,4]  [,5]   [,6]  [,7]  [,8]   [,9] [,10] [,11] [,12]

   "Home"  "A"  "B"  "C"  "Home"   "D"   "E"  "Home"  "F"  "G"   "H"   "I"

any solution would work for me either converting rows in to columns using string match of "Home"
or covert columns into rows using "Home" string match(transpose one)....

Data

x <- c("Home", "A", "B", "C", "Home", "D", "E", "Home", "F", "G", "H", "I")
x <- matrix(x)

The question has been solved...Thankyou for your response... I did it other way around...by running it in a loop and adding the row after every single node ends

List <- c() 

#loop start
nodes <- html_nodes(file,".class a b c ") %>% html_text()
List[[length(List)+1]] = nodes      
#loop ends

library(stringi)
catdf <- stri_list2matrix(List, byrow = TRUE)
catdf <- as.data.frame(catdf)
# create the data
x <- as.matrix(c("Home", "A", "B", "C", "Home", "D", "E", "Home", "F" ,"G" ,"H" ,"I"))

# split the data into a list of vectors, wherever "Home" is found
rowstarts <- x == "Home"
rowlist <- split(x, cumsum(rowstarts))

We can then use plyr 's ldply function to bind the list into a single data frame:

> plyr::ldply(rowlist, rbind)[-1]
     1 2 3    4    5
1 Home A B    C <NA>
2 Home D E <NA> <NA>
3 Home F G    H    I

And put all together it makes a short one-liner:

ldply(split(x, cumsum(x == "Home")), rbind)[-1]

Similar to C Braun's answer, but kept in base :

x = c("Home", "A", "B", "C", "Home", "D", "E", "Home", "F", "G", "H", "I")
s = split(x, cumsum(x == "Home"))
max_length = max(lengths(s))

t(sapply(s, function(i) {length(i) <- max_length; return(i)}))
#   [,1]   [,2] [,3] [,4] [,5]
# 1 "Home" "A"  "B"  "C"  NA  
# 2 "Home" "D"  "E"  NA   NA  
# 3 "Home" "F"  "G"  "H"  "I" 

I can not think of any built-in function to do this but you could create yours using base R function:

vector.split <- function(x, sep = "Home") {
    bool.sep <- x == sep
    split(x[!bool.sep], cumsum(bool.sep)[!bool.sep])
}

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