Транспонировать объект dplyr :: tbl - PullRequest
0 голосов
/ 26 апреля 2018

Я использую src_postgres для подключения и функцию dplyr :: tbl для извлечения данных из базы данных красного смещения. Я применил к нему несколько фильтров и функцию top, используя сам dplyr. Теперь мои данные выглядят как показано ниже:

   riid   day         hour 
   <dbl> <chr>       <chr>
 1 5542. "THURSDAY " 12   
 2 5862. "FRIDAY   " 15   
 3 5982. "TUESDAY  " 15   
 4 6022. WEDNESDAY   16 

My final output should be as below:
riid    MON   TUES  WED   THUR   FRI   SAT  SUN
5542                       12
5862                             15
5988           15
6022                 16

Я пробовал распространяться. Выдает следующую ошибку из-за типа класса:

Ошибка в UseMethod ("spread_"): нет подходящего метода для "spread_" применяется к объекту класса "c (" tbl_dbi "," tbl_sql "," tbl_lazy ", 'TBL') "

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

df_mon <- df2 %>% filter(day == 'MONDAY') %>% mutate(MONDAY = hour) %>% select(riid,MONDAY)
df_tue <- df2 %>% filter(day == 'TUESDAY') %>% mutate(TUESDAY = hour) %>% select(riid,TUESDAY)
df_wed <- df2 %>% filter(day == 'WEDNESDAY') %>% mutate(WEDNESDAY = hour) %>% select(riid,WEDNESDAY)
df_thu <- df2 %>% filter(day == 'THURSDAY') %>% mutate(THURSDAY = hour) %>% select(riid,THURSDAY)
df_fri <- df2 %>% filter(day == 'FRIDAY') %>% mutate(FRIDAY = hour) %>% select(riid,FRIDAY)

Можно ли написать все вышеизложенное в одном утверждении?

Любая помощь для более быстрого переноса это очень ценится.

EDIT Добавление dput объекта tbl:

structure(list(src = structure(list(con = <S4 object of class structure("PostgreSQLConnection", package = "RPostgreSQL")>, 
    disco = <environment>), .Names = c("con", "disco"), class = c("src_dbi", 
"src_sql", "src")), ops = structure(list(name = "select", x = structure(list(
    name = "filter", x = structure(list(name = "filter", x = structure(list(
        name = "group_by", x = structure(list(x = structure("SELECT riid,day,hour,sum(weightage) AS score FROM\n  (SELECT riid,day,hour,\n  POWER(2,(cast(datediff (seconds,convert_timezone('UTC','PKT',SYSDATE),TO_DATE(TO_CHAR(event_captured_dt,'mm/dd/yyyy hh24:mi:ss'),'mm/dd/yyyy hh24:mi:ss')) as decimal) / cast(7862400 as decimal))) AS weightage\n  FROM (\n  SELECT riid,convert_timezone('GMT','PKT',event_captured_dt) AS EVENT_CAPTURED_DT,\n  TO_CHAR(convert_timezone('GMT','PKT',event_captured_dt),'DAY') AS day,\n  TO_CHAR(convert_timezone('GMT','PKT',event_captured_dt),'HH24') AS hour\n  FROM Zameen_STO_DATA WHERE EVENT_CAPTURED_DT >= TO_DATE((sysdate -30),'yyyy-mm-dd') and LIST_ID = 4282\n  )) group by riid,day,hour", class = c("sql", 
        "character")), vars = c("riid", "day", "hour", "score"
        )), .Names = c("x", "vars"), class = c("op_base_remote", 
        "op_base", "op")), dots = structure(list(riid = riid, 
            day = day), .Names = c("riid", "day")), args = structure(list(
            add = FALSE), .Names = "add")), .Names = c("name", 
    "x", "dots", "args"), class = c("op_group_by", "op_single", 
    "op")), dots = structure(list(~min_rank(desc(~score)) <= 
        1), .Names = ""), args = list()), .Names = c("name", 
    "x", "dots", "args"), class = c("op_filter", "op_single", 
    "op")), dots = structure(list(~row_number() == 1), .Names = ""), 
    args = list()), .Names = c("name", "x", "dots", "args"), class = c("op_filter", 
"op_single", "op")), dots = structure(list(~riid, ~day, ~hour), class = "quosures", .Names = c("", 
"", "")), args = list()), .Names = c("name", "x", "dots", "args"
), class = c("op_select", "op_single", "op"))), .Names = c("src", 
"ops"), class = c("tbl_dbi", "tbl_sql", "tbl_lazy", "tbl"))

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Я пытался объединить ваши попытки нескольких строк в одну. Можете ли вы попробовать это и сообщить нам результат?

library(dplyr)

df %>%
  rowwise() %>%
  mutate(Mon = ifelse(day=='MONDAY', hour[day=='MONDAY'], NA),
         Tue = ifelse(day=='TUESDAY', hour[day=='TUESDAY'], NA),
         Wed = ifelse(day=='WEDNESDAY', hour[day=='WEDNESDAY'], NA),
         Thu = ifelse(day=='THURSDAY', hour[day=='THURSDAY'], NA),
         Fri = ifelse(day=='FRIDAY', hour[day=='FRIDAY'], NA),
         Sat = ifelse(day=='SATURDAY', hour[day=='SATURDAY'], NA),
         Sun = ifelse(day=='SUNDAY', hour[day=='SUNDAY'], NA)) %>%
  select(-day, -hour)

Вывод:

   riid Mon     Tue   Wed   Thu   Fri Sat   Sun  
1  5542 NA       NA    NA    12    NA NA    NA   
2  5862 NA       NA    NA    NA    15 NA    NA   
3  5982 NA       15    NA    NA    NA NA    NA   
4  6022 NA       NA    16    NA    NA NA    NA 

Пример данных:

# A tibble: 4 x 3
   riid day        hour
* <dbl> <chr>     <int>
1  5542 THURSDAY     12
2  5862 FRIDAY       15
3  5982 TUESDAY      15
4  6022 WEDNESDAY    16


Обновление: Можете ли вы попробовать подход ниже, используя data.table?

library(data.table)

dt <- setDT(df)[, c("Mon","Tue","Wed","Thu","Fri","Sat","Sun") := 
                  list(ifelse(day=='MONDAY', hour[day=='MONDAY'], NA),
                       ifelse(day=='TUESDAY', hour[day=='TUESDAY'], NA),
                       ifelse(day=='WEDNESDAY', hour[day=='WEDNESDAY'], NA),
                       ifelse(day=='THURSDAY', hour[day=='THURSDAY'], NA),
                       ifelse(day=='FRIDAY', hour[day=='FRIDAY'], NA),
                       ifelse(day=='SATURDAY', hour[day=='SATURDAY'], NA),
                       ifelse(day=='SUNDAY', hour[day=='SUNDAY'], NA))][, !c("day","hour"), with=F]
0 голосов
/ 01 мая 2018

Я думаю, что вам нужна возможность запуска функции tidyr::spread() для удаленного источника или базы данных. У меня есть PR для dbplyr, который пытается реализовать это здесь: https://github.com/tidyverse/dbplyr/pull/72,, вы можете попробовать его, используя: devtools::install_github("tidyverse/dbplyr", ref = devtools::github_pull(72)).

0 голосов
/ 26 апреля 2018

Использование dcast из reshape2 упаковки

> data
# A tibble: 4 x 3
   riid day    hour
  <dbl> <chr> <dbl>
1  1.00 TH     12.0
2  2.00 FR     15.0
3  3.00 TU     15.0
4  4.00 WE     16.0

> dcast(data, riid~day, value.var = "hour")

  riid FR TH TU WE
1    1 NA 12 NA NA
2    2 15 NA NA NA
3    3 NA NA 15 NA
4    4 NA NA NA 16

Далее, если вы хотите удалить NA, то

> z <- dcast(data, riid~day, value.var = "hour")
> z[is.na(z)] <- ""
> z
  riid FR TH TU WE
1    1    12      
2    2 15         
3    3       15   
4    4          16
...