R генерирует запаздывающее значение на основе непогашенного вычисленного значения во фрейме данных / таблице - PullRequest
0 голосов
/ 04 мая 2020

Поскольку я не настолько опытен в использовании циклов и связанных с ними oop -эквивалентных функций в R (например, purrr и apply() связанных функций, я думаю, что мою проблему довольно легко решить. Однако, потратив некоторое время без каких-либо результатов запрос сообщества кажется более разумным.

Чтобы понять проблему, представьте, что вы используете данные из пакета mtcars. Я хочу создать переменную, основанную на определенном значении Например, wt (вес). Поэтому фрейм данных упорядочен в порядке убывания следующим образом:

library(tidyverse)
library(mtcars)

df <- mtcars %>% 
  arrange(desc(wt)) 

Далее я хотел бы создать переменную, основанную на наибольшем значении wt. Я хочу разделить каждое значение на основе запаздывающего значения с определенным делителем (2), который еще не выполнен. Однако представьте, что значения не рассчитываются, код будет выглядеть следующим образом:

df <- mtcars %>% 
  arrange(desc(wt)) %>% 
  mutate(wt_2 = if_else(wt == max(wt),
                        wt,
                        lag(wt_2) / 2))

Я знаю, что mutate не работает должным образом, поскольку для аргумента else необходимо создать wt_2, но он будет работать, если указать новый раздел кода. Это будет означать:

df <- mtcars %>% 
  arrange(desc(wt)) %>% 
  mutate(wt_2 = if_else(wt == max(wt),
                        wt,
                        0)) %>% 
  mutate(wt_2 = if_else(wt_2 != max(wt),
                        lag(wt_2) / 2,
                        wt_2))

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

glimpse(df$wt_2)
 num [1:32] 5.425 2.71 1.36 0.68 0.34 ...

Третье значение должно быть 2.71 / 2 = 1.355. Четвертое значение 1.355 / 2 и так далее…

Новая переменная wt_2 должна , а не относится к wt, за исключением самого высокого значения (5,42 или 5,425 без округления). Каждому наблюдению должно быть присвоено запаздывающее (используя logi c of lag) значение предыдущего наблюдения той же переменной, деленное на 2 (или другое значение, но для этого примера я решил выбрать 2 в качестве делителя). Однако проблема заключается в том, что использование кода невозможно, поскольку значения присваиваются только первому наблюдению или первому и второму наблюдению. Можно было бы рассчитать каждое значение вручную, но также было бы возможно получить значения, рассчитанные более легко, с помощью функции, связанной с al oop.

1 Ответ

1 голос
/ 04 мая 2020

Поскольку R - векторизованный язык, циклы часто не нужны.

Здесь вы хотите, чтобы максимальное значение делилось на 2 в каждой строке, что эквивалентно делению на 2 на степень номера строки минус 1.

Следовательно, этот код должен давать ожидаемый результат:

df=mtcars %>% 
   select(wt) %>% 
   arrange(desc(wt)) %>% 
   mutate(wt_2 = max(wt) / 2^(row_number()-1))) %>% 
   round(2)

ожидаемый результат:

glimpse(df$wt_2)
#num [1:32] 5.42 2.71 1.36 0.68 0.34 0.17 0.08 0.04 0.02 0.01 ...
...