Преобразование скрипта SAS в R и создание цикла - PullRequest
0 голосов
/ 11 октября 2019

Я должен перевести свои сценарии в SAS на R, но у меня нет такого большого опыта в R, и я изо всех сил пытаюсь найти решение.

Вот мой код SAS:

%macro pluto(num);
    proc delete data=machine_tot; run;

    %do i=1 %to &num.;

        data tot;
            set campione(where=(month_1 >= &i.));

            month_2 = &i.;

            if (&i.-month_3) <= 0 then 
               w = 1;
            if (&i.-month_3) > 0 and (&i.-month_3) < 1 then 
               w = (1-(&i.-month_3));
            if (&i.-month_3) >=1 then 
               w = 0; 
        run;

        proc freq data = campione noprint;
            tables month_2 /out=output;
            weight w;  
        run;

        data cars;
            set val(keep=month_2 COUNT);
            cars_eq=floor(count);
            drop count;
        run;

        proc append data=cars out=machine_tot; run;
    %end;
%mend;

%pluto(&tot.);

В основном, где month_1> = 1, тогда month_2 должен быть 1, а значение разницы между 1 и month_3 должно привести к классификации w. Затем должны быть созданы некоторые таблицы, и процедура повторяется со значениями i от 1 до 24. В конце результаты связываются вместе с append.

Я понял, что должен построить цикл в R, нодо сих пор я мог просто написать код, чтобы сделать первый шаг (в идеале я должен повторить этот шаг для i от 1 до 24).

 tot <- campione %>% 
  filter(month_1 >= i)

tot <- tot %>% 
  mutate(month_2 = i)

tot <- tot %>% 
    mutate(diff = as.numeric(i - month_3))

tot <- tot %>% 
  mutate(w = case_when(
    diff <= 0 ~ 1, 
    (diff >0) & (diff < 1) ~ 1-diff, 
    diff >= 1 ~ 0)
  )

val <- tot %>% 
  group_by(month_3) %>% 
  summarise(COUNT = sum(w))

cars <- val %>% 
  group_by(month_2) %>% 
  summarise(floor(COUNT)) 

Любые предложения о том, как построить цикл, будут высоко оценены!

РЕДАКТИРОВАТЬ

Я редактирую вопрос, пытаясь объяснить лучше, что я ожидаюцикл делает (я не являюсь носителем английского языка и не являюсь экспертом по R, поэтому я надеюсь, что это будет достаточно ясно). У меня есть df, как в следующем:

month_1    month_3    id
1          2.3         1
5          6.6         2
7          7.65        3 
9          8.01        4
24         23.9        5
24         23.97       6
24         23.61       7
24         23.87       8
13         13.07       9

Я хочу принять во внимание цикл, где я <- 1:24 и сделать следующее: </p>

  1. group month_1 такчто я могу посчитать с первым циклом все данные с month_1> = i (с первым циклом это будет month_1> = 1, со вторым циклом все данные с month_1> = 2 и т. д.)
  2. создать переменнуюmonth_2 и присвойте ему значение соответствующего цикла (где month_1> = i, затем month_2 = i, т. е. где month_1> = 1, затем month_2 = 1, где month_1> = 2, затем month_2 = 2 и т. д.)
  3. создатьпеременная w, так что если i - month_3 <0, то w должно быть 1, если i - month_3> 0 и <1 w - (1- (i-month_3), если i - month_3> = 1, то w должно быть 0.
  4. сгруппировать по месяцу_3 и сумме w
  5. сгруппировать по месяцу_2 и сумме w
  6. снова запустить цикл со следующим значением, пока i = 24

Итак,например, для i = 24 есть 4 строки с month_1> = 24; month_2 должен быть = 24; w рассчитываются следующим образом:

  • id5 -> (24 - 23,90) = 0,10. 0,10 -> 0 и <1, поэтому w 1-0,10 = 0,90 </p>

  • id 6 -> 0,97

  • id 7 -> 0,61

  • id 8 -> 0,87

  • сгруппировать по month_3 и sum -> month_2 sum (w) 24 3,35

  • сгруппировать по месяцу_2 и сумме -> месяц_2 этаж (сумма (ш)) 24 3

Надеюсь, это более понятно ...

1 Ответ

2 голосов
/ 12 октября 2019

R имеет тенденцию работать лучше всего в векторизации, поэтому самый простой способ, который я вижу, это просто добавить столбец i к вашим данным. Использование expand.grid создаст и общий тиббл (фрейм данных), где tot повторяется для каждого i.

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

    library(tidyverse)
tot = 
tribble(
  ~month_1,    ~month_3,    ~id,
1,          2.3,         1,
5,          6.6,         2,
7,          7.65,        3, 
9,          8.01,        4,
24,         23.9,        5,
24,         23.97,       6,
24,         23.61,       7,
24,         23.87,       8,
13,         13.07,       9) 

expand_grid(i = seq(1,24) %>% as.numeric, tot) %>% 
  mutate(
    month_2 = case_when(
      month_1 >= i ~ i,
      TRUE ~ NA_real_
      ),
    diff = i - month_3,
    w = case_when(
      diff <= 0 ~ 1, 
      (diff >0) & (diff < 1) ~ 1-diff, 
      diff >= 1 ~ 0)
  ) %>% 
  group_by(i,month_3) %>% 
  mutate(COUNT = sum(w)) %>% 
  ungroup %>% 
  group_by(i,month_2) %>% 
  mutate(cars = floor(sum(w))) 

Как только вы подведете итог, он удалит остальные столбцы, поэтому группировка по месяцу_2 будет невозможна. Если вы хотите сгруппировать по обоим, чтобы получить минимальную сумму w для каждого i, это тоже сработало бы, просто добавьте month_2 в group_by, например group_by(i,month_2,month_3) %>% summarize(cars = floor(sum(w)).

...