简体   繁体   中英

Is there a way to move every other row in a column into a new column in R?

Challenge: I have a column in which there are several rows. For eg., the first row is "Fruit name" and second row is "Fruit Color" and it repeats for another fruit. I want to grab the every second row (Fruit color) and create a new column. In the original column only the fruit names remain

library(tidyverse)
df_before <- tribble(~Singlecolumn,"Apple","Red","Banana","Yellow","Kiwi","Grey","Grapes","Green")
df_before
Singlecolumn
<chr>
Apple               
Red             
Banana              
Yellow              
Kiwi                
Grey                
Grapes              
Green

#I would like to split this like below:
df_after <- tribble(~Column1, ~Column2, "Apple","Red","Banana","Yellow","Kiwi","Grey","Grapes","Green")
df_after

Column1 Column2
Apple   Red         
Banana  Yellow          
Kiwi    Grey            
Grapes  Green

I'm sure there is a easier way to do this using functions from tidyverse but couldn't find any info with a good deal of search. Would appreciate any pointers. Thanks in advance!

Easier option is to convert to a matrix with 2 columns and convert to data.frame in base R

as.data.frame(matrix(df_before$Singlecolumn, ncol = 2, byrow = TRUE))

But, we can also use tidyverse , where we create two groups with rep and then use pivot_wider to reshape from 'long' to 'wide' format

library(dplyr)
library(tidyr)
df_before %>%
  group_by(grp = str_c('Column', rep(1:2, length.out = n()))) %>%
  mutate(rn = row_number()) %>%
  ungroup %>%
  pivot_wider(names_from = grp, values_from = Singlecolumn) %>%
  select(-rn)
# A tibble: 4 x 2
#  Column1 Column2
#  <chr>   <chr>  
#1 Apple   Red    
#2 Banana  Yellow 
#3 Kiwi    Grey   
#4 Grapes  Green  

You could do it by indexing the odd and even numbered columns

# dummy data (please provide code to make a reproducible example in the future)
df1 <- data.frame(v1 = c("A", "a", "B", "b", "C", "c"))
# solution 
df2 <- data.frame(
  "col1" = df1[seq(1,length(df1[,1]),2), "v1"], 
  "col2" = df1[seq(2,length(df1[,1]),2), "v1"])

Here sequence is being used to give a vector of integers separated by 2, running from 1 or 2 to the length of the original dataframe using the seq() function, eg

seq(2,length(df1[,1]),2)
## [1] 2 4 6

That's then passed to the rows in the square braces of df[rows, columns] .

We can use vector recycling of logical values to get alternate data from df_before .

data.frame(Column1 = df_before$Singlecolumn[c(TRUE, FALSE)], 
           Column2 = df_before$Singlecolumn[c(FALSE, TRUE)])

#  Column1 Column2
#1   Apple     Red
#2  Banana  Yellow
#3    Kiwi    Grey
#4  Grapes   Green

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