цикл для умножения по столбцам

У меня есть фрейм данных со столбцами, помеченными sales1, sales2, price1, price2, и я хочу рассчитать доходы, умножая sales1 * price1 и так далее для каждого числа итеративным образом.

data <- data_frame(
  "sales1" = c(1, 2, 3),
  "sales2" = c(2, 3, 4),
  "price1" = c(3, 2, 2),
  "price2" = c(3, 3, 5))

data
# A tibble: 3 x 4
#  sales1 sales2 price1 price2
#   <dbl>  <dbl>  <dbl>  <dbl>
#1      1      2      3      3
#2      2      3      2      3
#3      3      4      2      5

Почему следующий код не работает?

data %>%
  mutate (
    for (i in seq_along(1:2)) {
      paste0("revenue",i) = paste0("sales",i) * paste0("price",i)
    }
  )

person Gulbas    schedule 02.11.2017    source источник
comment
взгляните на это   -  person acylam    schedule 02.11.2017


Ответы (2)


Предположим, что ваши столбцы уже упорядочены (sales1, sales2, price1, price2). Мы можем разделить фрейм данных на две части, а затем умножить их

data[grep("sales", names(data))] * data[grep("price", names(data))]

#  sales1 sales2
#1      3      6
#2      4      9
#3      6     20

Если столбцы еще не отсортированы по именам, мы можем отсортировать их с помощью order, а затем использовать приведенную выше команду.

data <- data[order(names(data))]
person Ronak Shah    schedule 02.11.2017

Этот ответ не краток. Для этого стоит взглянуть на существующий ответ @RonakShah!

Мой ответ предназначен для решения более широкой проблемы, связанной с трудностью попытки сделать это в tidyverse. Насколько я понимаю, это сложно, потому что данные в настоящее время не в «аккуратном» формате. Вместо этого вы можете создать аккуратный фрейм данных следующим образом:

library(tidyverse)

tidy_df <- data %>% 
  rownames_to_column() %>%
  gather(key, value, -rowname) %>% 
  extract(key, c("variable", "id"), "([a-z]+)([0-9]+)") %>%
  spread(variable, value)

Что затем делает окончательный расчет простым

tidy_df %>% mutate(revenue = sales * price)

#> # A tibble: 6 x 5
#>   rowname    id price sales revenue
#>     <chr> <chr> <dbl> <dbl>   <dbl>
#> 1       1     1     3     1       3
#> 2       1     2     3     2       6
#> 3       2     1     2     2       4
#> 4       2     2     3     3       9
#> 5       3     1     2     3       6
#> 6       3     2     5     4      20

Если вам нужно вернуть данные в исходный формат, вы можете это сделать, хотя мне это кажется неуклюжим (я уверен, что это можно как-то улучшить).

tidy_df %>% mutate(revenue = sales * price) %>%
  gather(key, value, -c(rowname, id)) %>%
  unite(key, key, id, sep = "") %>%
  spread(key, value) %>% 
  select(starts_with("price"), 
         starts_with("sales"),
         starts_with("revenue"))

#> # A tibble: 3 x 6
#>   price1 price2 sales1 sales2 revenue1 revenue2
#> *  <dbl>  <dbl>  <dbl>  <dbl>    <dbl>    <dbl>
#> 1      3      3      1      2        3        6
#> 2      2      3      2      3        4        9
#> 3      2      5      3      4        6       20
person markdly    schedule 02.11.2017
comment
Я вижу проблему в том, что данные не структурированы так, как вы описали. См. ниже другой пример df для контекста record <- c(seq_along(1:10)) store <- c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5) week <- c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2) sales_1 <- c(3, 3, 3, 3, 3, 2, 5, 1, 2, 10) sales_2 <- c(1, 2, 4, 5, 6, 2, 3, 6, 1, 8) price_1 <- runif(10, 2, 6) price_2 <- runif(10, 2, 6) df <- data_frame(record, store, week, sales_1, sales_2, price_1, price_2) У меня возникли трудности с уплотнением столбцов «продажи» и «цена» с использованием кода соломенного человека. Не могли бы вы провести меня, используя этот пример? - person Gulbas; 02.11.2017
comment
@ Гульбас, для меня это звучит как новый вопрос :). Если вы опубликуете его как один, я попытаюсь дать ответ (и вы вполне можете найти другие решения, которые лучше). Вы всегда можете вернуться к этому вопросу в своем новом вопросе, чтобы дать другим пользователям некоторый контекст относительно того, какой ответ вы ищете. - person markdly; 03.11.2017