Использование mutate и group_by для накатывания операции на строки - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть следующие данные:

country       year  sales
--------------------------
Afghanistan   1950   30
Afghanistan   1951   35
Albania       1950    0
Albania       1951    5
total         1950   30
total         1951   40

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

country       year  sales  ratio
---------------------------------
Afghanistan   1950   30     1
Afghanistan   1951   35     0.875
Albania       1950    0     0
Albania       1951    5     0.125
total         1950   30     1
total         1951   40     1

Я бы хотел использовать tidyverse (что я несколько новичок) для достижения этой цели, но я все еще несколько озадачен тем, как использовать mutate и group_by для достиженияэто (или даже если это лучший способ выполнить эту задачу в целом).

Я безуспешно пытался воспользоваться советом, данным в этой теме .То, что я пробовал, это:

library(tidyverse)
df <- df %>%
group_by(year) %>%
mutate(ratio = sales[country]/sales[country == "total"])

Но это создает столбец, называемый отношением, полным NA.Нужно ли использовать цикл или что-то еще?Я немного новичок в R, и я признаю, что до сих пор избегал петель.Просматривая документацию по циклам, я не мог придумать, как бы использовать один для анализа каждой комбинации страны и года и создать новый столбец.

1 Ответ

0 голосов
/ 29 сентября 2018

Вы можете группировать по странам, а затем делить продажи на максимальные продажи - я полагаю, что это total.

library(dplyr)
df %>% 
  group_by(year) %>% 
  mutate(ratio = sales / max(sales))
# A tibble: 6 x 4
# Groups:   year [2]
#  country      year sales ratio
#  <chr>       <int> <int> <dbl>
#1 Afghanistan  1950    30 1    
#2 Afghanistan  1951    35 0.875
#3 Albania      1950     0 0    
#4 Albania      1951     5 0.125
#5 total        1950    30 1    
#6 total        1951    40 1  

В base R

transform(df, ratio = ave(sales, year, FUN = function(x) x / max(x)))

Или с data.table

library(data.table)
setDT(df)[, ratio := sales / max(sales), by = year][]

данные

df <- structure(list(country = c("Afghanistan", "Afghanistan", "Albania", 
"Albania", "total", "total"), year = c(1950L, 1951L, 1950L, 1951L, 
1950L, 1951L), sales = c(30L, 35L, 0L, 5L, 30L, 40L)), .Names = c("country", 
"year", "sales"), class = "data.frame", row.names = c(NA, -6L
))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...