当前,我的数据框由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())
。您对下一步去有什么建议吗?
答案 0 :(得分:1)
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))
答案 1 :(得分:0)
使用末尾注释中可重复定义的DF
,确保DF[[1]]
是字符。然后使用grep
创建一个逻辑变量g
,每个输入行有一个元素,每个标题为TRUE,否则为FALSE。然后删除标题并使用setNames
将其拆分以设置结果列表的名称。最后,将每个列表组件转换为数字ts
系列,因为即使它们具有不同的长度,这些系列也可以绑定。现在cbind
将它们放在一起并转置。不使用任何软件包。
DF[[1]] <- as.character(DF[[1]])
g <- grepl("\\D", DF[[1]])
s <- setNames(split(DF[[1]][!g], cumsum(g)[!g]), DF[[1]][g])
t(do.call("cbind", lapply(s, function(x) ts(as.numeric(x)))))
给予:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
John Doe 7 45 42 978 3 6 8 9 0 11
Sally Jenkins 2 NA NA NA NA NA NA NA NA NA
可重复输入的形式假定为:
Lines <- "John Doe
7
45
42
978
3
6
8
9
0
11
Sally Jenkins
2"
DF <- read.table(text = Lines, as.is = TRUE, sep = ";")