Мутировать несколько столбцов одного значения в кадре данных, используя один вектор - PullRequest
0 голосов
/ 07 ноября 2019

Я пытаюсь сделать что-то вроде ниже: заполняя таблицу, умножая вектор слева (df2) на каждое из значений в raw 2 (df1: y1 до y10). На самом деле у меня есть больший набор данных, но это воспроизводимо.

enter image description here

фреймы данных

df1:
y1    y2    y3    y4
5     10    15    20

df2:
perc
0.08
0.02
0.08
0.12
0.20
0.30
0.12
0.03
0.01

коды, которые я пробовал:

try1 <- df2 %>% mutate_each_(.funs = funs(. * df1[1,]), .cols = vars(contains("y")))

try2 <- df2 %>% mutate_each_(funs = funs(. * df1[1,]), vars = vars(contains("y")))

try3 <- df2 %>% mutate_at(.funs = funs(X = .*df1[1,1:5]), .vars = c(y1:y5))

try4 <- df1 %>% mutate_each(funs(op = .*df2), y1:y5)

try5 <- cbind(df1,apply(df1[1,1:5],2, function(x) x*df2))

try6 <- cbind(df2,apply(df2[,1],2, function(x) x*df1[1,1:5]))

В концеЯ хотел бы переименовать каждый столбец y1 = 2010 ... y5 = 2015, так как каждый представляет значения для одного года.

Любая рекомендация очень приветствуется.

Отредактировано :

Поскольку это будет матричная операция, df1 теперь является матрицей с большим количеством элементов N [3 х 10]. df2 - это то же самое [1 x 9].

Я хочу закончить df O [27 x 10], как объяснено на рисунке ниже:

enter image description here

enter image description here

Где каждое значение M (df2) умножает каждое значение N (df1).

Ответы [ 2 ]

2 голосов
/ 07 ноября 2019

Это умножение матриц

y = seq(5, 20, by = 5)
x = c(0.08, 0.02, 0.08, 0.12, 0.2, 0.3, 0.12, 0.03, 0.01)

y %*% t(x)
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
# [1,]  0.4  0.1  0.4  0.6    1  1.5  0.6 0.15 0.05
# [2,]  0.8  0.2  0.8  1.2    2  3.0  1.2 0.30 0.10
# [3,]  1.2  0.3  1.2  1.8    3  4.5  1.8 0.45 0.15
# [4,]  1.6  0.4  1.6  2.4    4  6.0  2.4 0.60 0.20

Функция outer делает это более широко, позволяя вам указать любую двоичную операцию (но по умолчанию *).

outer(y, x)
# same result
2 голосов
/ 07 ноября 2019

Простое умножение матриц может сделать это легко.

df <- as.data.frame(as.matrix(df2) %*% as.matrix(df1))

Если вы хотите использовать dplyr, вы можете сделать это.

library(dplyr)

df <- cbind(df2, df1) %>%
  mutate_at(vars(-perc), ~ perc * .) %>%
  select(-perc)

Если вы действительно хотите придерживаться"Tidyverse", вы можете использовать crossing из tidyr вместо cbind. Это будет работать для нескольких строк в df1.

library(tidyr)
library(tibble)

df2 %>%
  rowid_to_column("group") %>%
  crossing(df1) %>%
  mutate_at(vars(-group, -perc), ~ perc * .) %>%
  select(-perc)

В любом случае, вы можете переименовать результирующий фрейм данных, используя names().

names(df) <- 2010:2013

Позже Редактировать (Еще несколько опций):

Используется purrr из тидиверса, и он может быть наиболее чистым для вас, если вы начнете с двух фреймов данных, как ваш пример.

library(purrr)

map_dfc(df1, ~ . * df2) %>%
  set_names(2009 + seq_along(df1))

Выможет в основном выполнить то же самое в базе, но это вернет матрицу, а не фрейм данных, если мы не преобразуем его.

setNames(as.data.frame(sapply(df1,  function(x) t(x * df2))), 2009 + seq_along(df1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...