首页 > 解决方案 > 将具有一列的数据框转换为R中的多列

问题描述

目前我的数据框由 1 列 2326 行组成。我想将我的数据框转换为由 11 行组成。更具体地说,我当前的数据框看起来像

John Doe
7
45
42
978
3
6
8
9
0
11
Sally Jenkins
2

等等

我希望我的数据框看起来像:

John Doe        7  45  42  978  3  6  8  9  0  11 
Sally Jenkins   2  

每个人是一行,然后他们的统计数据是行中的一个单独的列。有些人缺少统计数据,因此我无法根据每个人姓名之间的行数进行区分。

我已经尝试使用t()以及reshape(transform()). 你对下一步去哪里有什么建议吗?

标签: rdataframetransformreshapetranspose

解决方案


1)一个选项是根据字母的存在创建一个分组变量,方法summarise是创建一个list输出并将unnest_wider其更改list为一组新列

library(dplyr)
library(tidyr)
library(stringr)
df1  %>%
      group_by(grp = cumsum(str_detect(col1, "[A-Za-z]"))) %>%
      group_by(coln = first(col1), .add = TRUE) %>%
      slice(-1) %>%
      summarise(out = list(as.list(as.numeric(col1))))  %>%
      unnest_wider(c(out)) %>%
      ungroup %>%
      select(-grp) %>%
      rename_at(-1, ~ str_c('new_col', seq_along(.)))
# A tibble: 2 x 11
#  coln          new_col1 new_col2 new_col3 new_col4 new_col5 new_col6 new_col7 new_col8 new_col9 new_col10
#  <chr>            <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>     <dbl>
#1 John Doe             7       45       42      978        3        6        8        9        0        11
#2 Sally Jenkins        2       NA       NA       NA       NA       NA       NA       NA       NA        NA

2)或使用base R(不使用包)

grp <- with(df1, ave(col1, cumsum(grepl('[A-Za-z]', col1)), 
     FUN = function(x) x[1]))
aggregate(values ~ ind, stack(split(as.numeric(df1$col1[duplicated(grp)]), 
           grp[duplicated(grp)])),  FUN = I)
#            ind                            values
#1      John Doe 7, 45, 42, 978, 3, 6, 8, 9, 0, 11
#2 Sally Jenkins                                 2

数据

df1 <- structure(list(col1 = c("John Doe", "7", "45", "42", "978", "3", 
"6", "8", "9", "0", "11", "Sally Jenkins", "2")), class = "data.frame", 
row.names = c(NA, 
-13L))

推荐阅读