在每隔一行上拆分变量以在data.frame中形成两个新列

时间:2018-12-19 02:03:37

标签: r dplyr

抓取pdf后,我有一个带有chr文本var的数据框:

df = data.frame(text = c("abc","def","abc","def"))

我的问题是如何将其转换为:

df = data.frame(text1 = c("abc","abc"),text2=c("def","def"))

我能够为行建立索引并手动重建新的df,但很好奇是否可以在dplyr管道内完成。

我能够找到的所有解决方案都涉及将每一行拆分,而不是将变量的整个行拆分为新列。

2 个答案:

答案 0 :(得分:6)

使用dplyr,您可以创建一个新的列(ind)进行分组,每隔一行的值都相同,然后我们group_by ind并创建一个序列列(idspread数据分成两列。

library(dplyr)
library(tidyr)

df %>%
  mutate(ind = rep(c(1, 2),length.out = n())) %>%
  group_by(ind) %>%
  mutate(id = row_number()) %>%
  spread(ind, text) %>%
  select(-id)


#   `1`   `2`  
#  <fct> <fct>
#1 abc   def  
#2 abc   def  

R的基本选项是将split df分成单独的数据帧,每隔一行使用repcbind一起创建一个序列以形成2列数据​​帧。

do.call("cbind", split(df, rep(c(1, 2), length.out = nrow(df))))

#  text text
#1  abc  def
#3  abc  def

答案 1 :(得分:4)

我们可以在base R中进行此操作。使用matrix路由将向量/列重新排列为matrix,然后将其转换为data.frameas.data.frame)。由于列数是常量,即2,因此请在ncol

中指定该值
as.data.frame(matrix(df$text, ncol = 2, byrow = TRUE, 
      dimnames = list(NULL, c('text1', 'text2'))))
#   text1 text2
#1   abc   def
#2   abc   def

或者另一个选择是创建一系列备用ID(利用回收利用)后的unstack中的base R

unstack(transform(df, val = paste0('text', 1:2)), text ~ val)
#    text1 text2
#1   abc   def
#2   abc   def

或者我们可以split放入listvector中,然后cbind一起

as.data.frame(do.call(cbind, split(as.character(df$text), 1:2)))
#   1   2
#1 abc def
#2 abc def

或者另一个选择是dcast中的data.table

library(data.table)
dcast(setDT(df), rowid(text)~ text)[, text := NULL][]

数据

df <- data.frame(text = c("abc","def","abc","def"))