Добавить набор данных с данными в определенных столбцах - PullRequest
2 голосов
/ 19 января 2020

Если это мой тестовый набор данных

    Id    Col1_ABC   Col2_BCD    Col3_CBD     Col1_ABC_1    Col2_BCD_1    Col3_CBD_1
    1     Yes        No          No           Yes           Yes           No
    2     No         No          No           Yes           No            Yes
    3     Yes        Yes         Yes          No            Yes           No
    4     Yes        No          Yes
    5     No         No          No

Мне нравится перемещать данные в столбцах с конечным значением _1 ниже данных без конечного значения _1 < если это имеет смысл>. Окончательный набор данных должен выглядеть так:

    Id    Col1_ABC   Col2_BCD    Col3_CBD   Status   
    1     Yes        No          No         Pre  
    2     No         No          No         Pre  
    3     Yes        Yes         Yes        Pre  
    4     Yes        No          Yes        Pre
    5     No         No          No         Pre

    1     Yes        Yes         No         Post
    2     Yes        No          Yes        Post
    3     No         Yes         No         Post

Я знаю очень неуклюжий способ сделать это, который включает поднаборы, переименование и выполнение rbind, но я ищу более эффективный подход, любые предложения очень оценены.

Ответы [ 2 ]

2 голосов
/ 20 января 2020

Другой вариант, включающий dplyr и tidyr, может быть:

df %>%
 pivot_longer(-Id) %>%
 mutate(Status = if_else(grepl("_1", name, fixed = TRUE), "Post", "Pre"),
        name = gsub("^([^_]*_[^_]*)_.*$", "\\1", name)) %>%
 pivot_wider(names_from = "name", values_from = "value") %>%
 filter_all(all_vars(!is.na(.))) %>%
 arrange(Status)

     Id Status Col1_ABC Col2_BCD Col3_CBD
  <int> <chr>  <chr>    <chr>    <chr>   
1     1 Post   Yes      Yes      No      
2     2 Post   Yes      No       Yes     
3     3 Post   No       Yes      No      
4     1 Pre    Yes      No       No      
5     2 Pre    No       No       No      
6     3 Pre    Yes      Yes      Yes     
7     4 Pre    Yes      No       Yes     
8     5 Pre    No       No       No 
1 голос
/ 19 января 2020

Мы можем использовать pivot_longer из tidyr, чтобы изменить форму столбцов с «широкого» на «длинный» после изменения имен столбцов, у которых нет нумерации c, заканчивающейся rename_at

library(dplyr)
library(tidyr)
library(stringr)
df1 %>%
    rename_at(-1, ~ str_replace(., '([A-Z])$', '\\1_0')) %>% 
    pivot_longer(cols = -Id, names_to = c( ".value", "Status"),
         names_sep = "_(?=[0-9])", values_drop_na = TRUE) %>%
    mutate(Status = factor(Status, levels = 0:1, labels = c("Pre", "Post"))) %>%
    arrange(Status) 
#   Id Status Col1_ABC Col2_BCD Col3_CBD
#1  1    Pre      Yes       No       No
#2  2    Pre       No       No       No
#3  3    Pre      Yes      Yes      Yes
#4  4    Pre      Yes       No      Yes
#5  5    Pre       No       No       No
#6  1   Post      Yes      Yes       No
#7  2   Post      Yes       No      Yes
#8  3   Post       No      Yes       No

Или другой вариант melt из data.table, где мы указываем patterns в measure для преобразования данных из «широкого» в «длинный» формат

library(data.table)
melt(setDT(df1), measure = patterns("Col1_ABC", "Col2_BCD", "Col3_CBD"), 
    na.rm = TRUE, variable.name = 'Status',
   value.name = c("Col1_ABC", "Col2_BCD", "Col3_CBD"))[,
         Status := c("Pre", "Post")[Status]][]
#   Id Status Col1_ABC Col2_BCD Col3_CBD
#1:  1    Pre      Yes       No       No
#2:  2    Pre       No       No       No
#3:  3    Pre      Yes      Yes      Yes
#4:  4    Pre      Yes       No      Yes
#5:  5    Pre       No       No       No
#6:  1   Post      Yes      Yes       No
#7:  2   Post      Yes       No      Yes
#8:  3   Post       No      Yes       No

данные

df1 <- structure(list(Id = 1:5, Col1_ABC = c("Yes", "No", "Yes", "Yes", 
"No"), Col2_BCD = c("No", "No", "Yes", "No", "No"), Col3_CBD = c("No", 
"No", "Yes", "Yes", "No"), Col1_ABC_1 = c("Yes", "Yes", "No", 
NA, NA), Col2_BCD_1 = c("Yes", "No", "Yes", NA, NA), Col3_CBD_1 = c("No", 
"Yes", "No", NA, NA)), class = "data.frame", row.names = c(NA, 
-5L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...