Обработка столбца в R - данные хранятся в виде имени столбца - PullRequest
0 голосов
/ 01 октября 2018

У меня есть фрейм данных странно отформатированных данных, где информация хранится как часть имени столбца.

library(tidyverse)

Ihave <- frame_data(
  ~ID,~group,~AAA_info2_BBB,~CCC_info3_DDD,
  "first",  1, as.Date("1970-01-01"), as.Date("1970-01-02"),
  "second", 2, as.Date("1971-01-01"), as.Date("1971-01-02"),
  "third",  3, as.Date("1972-01-01"), as.Date("1972-01-02"),
)

# A tibble: 3 x 4
  ID     group AAA_info2_BBB CCC_info3_DDD
  <chr>  <dbl> <date>        <date>       
1 first      1 1970-01-01    1970-01-02   
2 second     2 1971-01-01    1971-01-02   
3 third      3 1972-01-01    1972-01-02   

Мне нужно вернуть информацию обратно во фрейм данных, как показано ниже

Iwant <-  frame_data(
  ~ID,~group,~source,~variable,~value,~period,
  "first",  1, "AAA", "info1", as.Date("1970-01-01"), "BBB",
  "second", 2, "AAA", "info1", as.Date("1971-01-01"), "BBB",
  "third",  3, "AAA", "info1", as.Date("1972-01-01"), "BBB",
  "first",  1, "CCC", "info2", as.Date("1970-01-02"), "DDD",
  "second", 2, "CCC", "info2", as.Date("1971-01-02"), "DDD",
  "third",  3, "CCC", "info2", as.Date("1972-01-02"), "DDD",
)

# A tibble: 6 x 6
  ID     group source variable value      period
  <chr>  <dbl> <chr>  <chr>    <date>     <chr> 
1 first      1 AAA    info1    1970-01-01 BBB   
2 second     2 AAA    info1    1971-01-01 BBB   
3 third      3 AAA    info1    1972-01-01 BBB   
4 first      1 CCC    info2    1970-01-02 DDD   
5 second     2 CCC    info2    1971-01-02 DDD   
6 third      3 CCC    info2    1972-01-02 DDD   

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

my_fun <- function(df, one_var) {

  # Get string from called column name
  one_var_char <- 
    enquo(one_var) %>%  
    { as.character(.)[2] }  

  # Split string across "_" and return character vector
  one_var_char_splitted <- 
    one_var_char %>% 
    { strsplit(., "_")[[1]] }

  new_one_var <- one_var_char_splitted[2]

  names(df)[names(df) == one_var_char] <- new_one_var

  df %>%
    select(new_one_var) %>% 
    data.frame(source = one_var_char_splitted[1],
               period = one_var_char_splitted[3] )
}

, которая возвращает (как и ожидалось)

Ihave %>% 
  select(ID, group, AAA_info2_BBB) %>% 
  my_fun(AAA_info2_BBB)

       info2 source period
1 1970-01-01    AAA    BBB
2 1971-01-01    AAA    BBB
3 1972-01-01    AAA    BBB

Но я не могу "сопоставить" этоФункция на фрейм данных Ihave для получения желаемого Iwant.Я попробовал несколько смесей purrr::map, но безуспешно.Есть ли недостаток в моем подходе?Я что-то пропустил?

Любая помощь очень ценится!

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Та же идея, что и gather, тогда separate, но просто для разнообразия вот метод data.table с использованием melt и tstrsplit

library(data.table)
setDT(Ihave)

melt(Ihave, c('ID', 'group'))[, 
  c('source', 'variable', 'period') := tstrsplit(variable, '_')]

#        ID group variable      value source period
# 1:  first     1    info2 1970-01-01    AAA    BBB
# 2: second     2    info2 1971-01-01    AAA    BBB
# 3:  third     3    info2 1972-01-01    AAA    BBB
# 4:  first     1    info3 1970-01-02    CCC    DDD
# 5: second     2    info3 1971-01-02    CCC    DDD
# 6:  third     3    info3 1972-01-02    CCC    DDD
0 голосов
/ 01 октября 2018

Я сделал это до того, как увидел комментарии @ aosmith, которые точны:

library(dplyr)
library(tidyr)
Ihave %>%
  gather(source, value, -ID, -group) %>%
  separate(source, into = c("source", "variable", "period"), sep = "_")
# # A tibble: 6 x 6
#   ID     group source variable period value     
#   <chr>  <dbl> <chr>  <chr>    <chr>  <date>    
# 1 first      1 AAA    info2    BBB    1970-01-01
# 2 second     2 AAA    info2    BBB    1971-01-01
# 3 third      3 AAA    info2    BBB    1972-01-01
# 4 first      1 CCC    info3    DDD    1970-01-02
# 5 second     2 CCC    info3    DDD    1971-01-02
# 6 third      3 CCC    info3    DDD    1972-01-02

Это зависит от числа _ разделенных полей, которые являются постоянными, упорядоченными и известными.Если формат никогда не меняется, ты в порядке.В противном случае вам нужно написать что-то более конкретное / нестандартное, чтобы иметь дело с любым вариантом.

Вам не нужно явно вызывать library(dplyr) или tidyr, если вы уже загружаете library(tidyverse).(Я включаю их здесь в случае, если (а) кто-то приходит и не загружает явно все 25 пакетов, или (б) вы думали, что вам нужны все из них, но хотите сократить время загрузки, обрезая неиспользуемые пакеты.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...