Развернуть фрейм данных на основе значений столбцов - PullRequest
3 голосов
/ 23 июня 2019

У меня есть такой фрейм данных:

    Title Female Male Asian HispanicLatino White
1   Title1      2    3     1              1     3
2   Title2      1    5    NA              1     5
3   Title3     NA    2    NA             NA     2

Я хочу расширить это так, чтобы в заголовке 1 было две строки для женщины и три для мужчины, а также другие столбцы (яесть еще много столбцов).

Я пробовал разные вещи, и следующее технически работает, но не идеально.

    df[is.na(df)] <- 0

    dfM <- uncount(df, df$Male)
    dfM$Sex <- "M"


    dfF <- uncount(df, df$Female)
    dfF$Sex <- "F"

    df <- rbind.fill(dfF, dfM)

Который производит

   Title Female Male Asian  HispanicLatino   White Sex
1    Title1      2    3     1              1     3   F
2    Title1      2    3     1              1     3   F
3    Title2      1    5     0              1     5   F
4    Title1      2    3     1              1     3   M
5    Title1      2    3     1              1     3   M
6    Title1      2    3     1              1     3   M
7    Title2      1    5     0              1     5   M
8    Title2      1    5     0              1     5   M
9    Title2      1    5     0              1     5   M
10   Title2      1    5     0              1     5   M
11   Title2      1    5     0              1     5   M
12   Title3      0    2     0              0     2   M
13   Title3      0    2     0              0     2   M

Интересно посмотреть, есть ли гораздо более простой способ сделать это.

Вот некоторые данные:

dput(df)
structure(list(Title = structure(1:3, .Label = c("Title1", 
"Title2", "Title3"), class = "factor"), Female = c(2L, 1L, NA
), Male = c(3L, 5L, 2L), Asian = c(1L, NA, NA), HispanicLatino = c(1L, 
1L, NA), White = c(3L, 5L, 2L)), .Names = c("Title", "Female", 
"Male", "Asian", "HispanicLatino", "White"), class = "data.frame", row.names = c(NA, 
-3L))

Ответы [ 2 ]

2 голосов
/ 24 июня 2019

Опцией будет map для циклического расширения столбцов после replace с NA с 0 при создании столбца .id ('Sex')

library(tidyverse)
map_df(setNames(c("Female", "Male"), c("F", "M")), ~ 
       df %>%
           mutate_at(vars(.x), replace_na, 0) %>% 
           uncount(!! rlang::sym(.x), .remove = FALSE), .id = 'Sex') %>%
       mutate_at(3:6, replace_na, 0)
#   Sex  Title Female Male Asian HispanicLatino White
#1    F Title1      2    3     1              1     3
#2    F Title1      2    3     1              1     3
#3    F Title2      1    5     0              1     5
#4    M Title1      2    3     1              1     3
#5    M Title1      2    3     1              1     3
#6    M Title1      2    3     1              1     3
#7    M Title2      1    5     0              1     5
#8    M Title2      1    5     0              1     5
#9    M Title2      1    5     0              1     5
#10   M Title2      1    5     0              1     5
#11   M Title2      1    5     0              1     5
#12   M Title3      0    2     0              0     2
#13   M Title3      0    2     0              0     2
0 голосов
/ 24 июня 2019

Используя базу R, мы можем использовать rep для повторения числа строк после преобразования NA s в 0.

df[is.na(df)] <- 0 #Don't use this line if NA needed in final output.
df[rep(seq_len(nrow(df)), rowSums(df[c("Female", "Male")])), ]

#     Title Female Male Asian HispanicLatino White
#1   Title1      2    3     1              1     3
#1.1 Title1      2    3     1              1     3
#1.2 Title1      2    3     1              1     3
#1.3 Title1      2    3     1              1     3
#1.4 Title1      2    3     1              1     3
#2   Title2      1    5     0              1     5
#2.1 Title2      1    5     0              1     5
#2.2 Title2      1    5     0              1     5
#2.3 Title2      1    5     0              1     5
#2.4 Title2      1    5     0              1     5
#2.5 Title2      1    5     0              1     5
#3   Title3      0    2     0              0     2
#3.1 Title3      0    2     0              0     2

Поскольку в конечном результате все NA s конвертируются в 0мы заменяем NA на 0 здесь.Если мы хотим, чтобы NA s были сохранены как NA в конечном выводе, мы можем вместо этого использовать na.rm = TRUE в rowSums.

Если важен порядок строк, мы можем использовать повторение индивидуально.Мы также можем удалить имена строк.

row_inds <- seq_len(nrow(df))
df1 <- df[c(rep(row_inds, df$Female), rep(row_inds, df$Male)), ]
rownames(df1) <- NULL
df1

#   Title Female Male Asian HispanicLatino White
#1  Title1      2    3     1              1     3
#2  Title1      2    3     1              1     3
#3  Title2      1    5     0              1     5
#4  Title1      2    3     1              1     3
#5  Title1      2    3     1              1     3
#6  Title1      2    3     1              1     3
#7  Title2      1    5     0              1     5
#8  Title2      1    5     0              1     5
#9  Title2      1    5     0              1     5
#10 Title2      1    5     0              1     5
#11 Title2      1    5     0              1     5
#12 Title3      0    2     0              0     2
#13 Title3      0    2     0              0     2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...