Преобразование фрейма данных с одним столбцом во множество столбцов в R - PullRequest
0 голосов
/ 19 февраля 2020

В настоящее время мой фрейм данных состоит из 1 столбца с 2326 строками. Я хочу преобразовать мой фрейм данных, чтобы он состоял из 11 строк. Более конкретно, мой текущий фрейм данных выглядит как

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

et c.

Я хочу, чтобы мой фрейм данных выглядел следующим образом:

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

Каждый человек представляет собой строку, а затем его статистика представляет собой отдельный столбец в строке. Некоторым людям не хватает статистики c, поэтому я не могу разделить их по количеству строк между именами каждого человека.

Я пытался использовать t() и reshape(transform()). Есть ли у вас какие-либо предложения о том, где go дальше?

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Используя DF, определенно воспроизводимый в примечании в конце, убедитесь, что DF[[1]] является символом. Затем используйте grep, чтобы создать логическую переменную g с одним элементом на строку ввода, которая равна TRUE для каждого заголовка и FALSE в противном случае. Затем удалите заголовки и разделите их, используя setNames, чтобы задать имена в результирующем списке. Наконец, преобразуйте каждый компонент списка в ряд числовых c ts, поскольку такие ряды могут быть cbind'ed, даже если они имеют разную длину. Теперь 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 = ";")
0 голосов
/ 19 февраля 2020

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

data

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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...