r - 将具有一列的数据框转换为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())
. 你对下一步去哪里有什么建议吗?
解决方案
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))