#r #dplyr
#r #dplyr
Вопрос:
Итак, у меня есть фрейм данных следующим образом:
ID A B C
1 .3 .3 .4
2 .1 .5 .4
3 .7 0 .3
И у меня есть следующее:
ID VALUE
1 10
1 5
1 100
2 30
3 34
2 12
Я в основном хочу умножить my VALUE
на my Df1
, чтобы получить эти переменные. Таким образом, для каждого экземпляра идентификатора используются соответствующие множители. Здесь требуется решение Dplyr.
Моя конечная цель:
ID VALUE A B C
1 10 3 3 4
1 5 1.5 1.5 2
1 100 30 30 40
2 30 3 15 12
3 34 23.8 0 10.2
2 12 1.2 6 4.8
РЕДАКТИРОВАТЬ: переменная ID является символом
Ответ №1:
Один из способов — объединить два ID
, а затем умножить на те переменные, которые вы хотите.
library(tibble)
library(dplyr)
df1 <- tribble(
~ID, ~A, ~B, ~C,
1, .3, .3, .4,
2, .1, .5, .4,
3, .7, 0, .3
)
df2 <- tribble(
~ID, ~VALUE,
1, 10,
1, 5,
1, 100,
2, 30,
3, 34,
2, 12
)
left_join(
df2, df1, by = "ID"
) %>%
mutate_at(vars(A, B, C), ~VALUE*.)
# A tibble: 6 x 5
ID VALUE A B C
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1 10 3 3 4
2 1 5 1.5 1.5 2
3 1 100 30 30 40
4 2 30 3 15 12
5 3 34 23.8 0 10.2
6 2 12 1.2 6 4.8
Редактировать:
Чтобы изменить все переменные сразу, замените последний фрагмент кода на:
left_join(
df2, df1, by = "ID"
) %>%
mutate(across(-c(ID, VALUE), ~VALUE*.x))
Комментарии:
1. Обратите внимание, что
mutate_at()
и другие глаголы с областью действия заменяютсяdplyr
. Рекомендуется использовать значениеmutate
across
, как вmutate(across(c(A, B, C), ~ VALUE * .x))
2. Хорошо, это близко; однако мои данные содержат около 100 переменных, то есть больше, чем A, B и C.
3. @JoaoPedroMacalos спасибо за к вашему сведению, не знал
4. @JohnThomas вы могли бы использовать аккуратный выбор для этих 100 переменных. или другое решение будет включать некоторое длинное / широкое преобразование, чтобы упростить операцию
5. @JoaoPedroMacalos это почти работает, но everything() по-прежнему включает переменную ID, которая является символом, поэтому она не работает. По сути, он должен работать с каждой переменной, КРОМЕ ID, первого столбца и только символьной переменной
Ответ №2:
В базе R вы могли бы сделать:
n <- ncol(df1)
A <- merge(df1, df2[c(1, rep(2, n-1))])
A[2:n] * A[(2:n) n - 1]
A B C
1 3.0 3.0 4.0
2 1.5 1.5 2.0
3 30.0 30.0 40.0
4 3.0 15.0 12.0
5 1.2 6.0 4.8
6 23.8 0.0 10.2
Ответ №3:
Мы можем использовать data.table
library(data.table)
nm1 <- names(df1)[-1]
setDT(df2)[setDT(df1), (nm1) := lapply(mget(paste0("i.", nm1)),
`*`, VALUE),on = .(ID)]
-вывод
df2
# ID VALUE A B C
#1: 1 10 3.0 3.0 4.0
#2: 1 5 1.5 1.5 2.0
#3: 1 100 30.0 30.0 40.0
#4: 2 30 3.0 15.0 12.0
#5: 3 34 23.8 0.0 10.2
#6: 2 12 1.2 6.0 4.8