Как умножить на отдельные фреймы данных и применить функцию для получения нового фрейма данных с результатом в R - PullRequest
1 голос
/ 19 июня 2020

У меня есть два фрейма данных. Один из них имеет коды (1 или -1) для разных идентификаторов.

data.1 <- read.csv(text = "
IDs qt1 qt2 qt3
pl1 -1 -1 -1
pl2 1 -1 1
pl3 1 1 1
pl4 -1 -1 -1
pl5 1 1 1
pl6 1 1 1
pl7 1 -1 1
pl8 1 1 1 
pl9 -1 -1 -1
pl0 -1 -1 -1
")

И еще один фрейм данных с тремя переменными, параметрами и оценками.

Data.2 <- read.csv(text = "
variable parameter estimate
varA a0 2.3
varA a1 0.859
varA a2 0.527
varA a3 0.774
VarB b0 19.08
VarB b1 0.412
VarB b2 0.022
VarB b3 0.448
VarC c0 5.4
VarC c1 0.492
VarC c2 0.094
VarC c3 0.971
")

Для каждого идентификатора мне нужно оценить значение каждой переменной. Например, для pl1 и VarA мне нужно вычислить значение a0 + (a1 * qt1) + (a2 * qt2) + (a3 * qt3).

Ожидаемый результат для каждого из идентификаторов будет быть чем-то вроде этого:

enter image description here

Конечно, это пример макета, и у меня есть сотни идентификаторов и переменных. Следовательно, мне понадобится какой-нибудь автоматический c способ сделать это. Я изучал варианты с dplyr::rowwise и пытался написать функцию, но не мог найти способ сделать разумный код.

Любая помощь будет очень признательна.

Спасибо

Ответы [ 2 ]

0 голосов
/ 19 июня 2020

Рассмотрим перекрестное слияние фреймов данных после небольшого изменения формы до широкого формата. Затем запустите указанный расчет без каких-либо циклов.

# ADD COLUMN + RESHAPE WIDE
wide_data.2 <- reshape(transform(data.2, var_letter=gsub("[a-z]", "", parameter)), 
                       idvar = "variable", v.names = "estimate",  drop = "parameter",
                       timevar = "var_letter", direction = "wide")

# CROSS JOIN MERGE + CALCULATION
merge_data <- within(merge(wide_data.2, data.1, by=NULL), {
        calc_value <- estimate.0 + (estimate.1*qt1) + (estimate.2*qt2) + (estimate.3*qt3)
})

# RESHAPE WIDE
wide_merge_data <- reshape(merge_data[c("IDs", "calc_value", "variable")], 
                           idvar = "IDs", v.names = "calc_value", 
                           timevar = "variable", new.row.names = 1:nrow(data.1),
                           direction = "wide")
wide_merge_data 

#    IDs calc_value.VarA calc_value.VarB calc_value.VarC
# 1  pl1           0.140          18.198           3.843
# 2  pl2           3.406          19.918           6.769
# 3  pl3           4.460          19.962           6.957
# 4  pl4           0.140          18.198           3.843
# 5  pl5           4.460          19.962           6.957
# 6  pl6           4.460          19.962           6.957
# 7  pl7           3.406          19.918           6.769
# 8  pl8           4.460          19.962           6.957
# 9  pl9           0.140          18.198           3.843
# 10 pl0           0.140          18.198           3.843
0 голосов
/ 19 июня 2020

Вы можете разделить значения qt по строкам и вставить 1 в качестве первого значения, разделить оценки по переменной, а затем умножить и суммировать:

qt_vals <- split(cbind(qt0 = 1, data.1[-1]), f = data.1$IDs)
vals <- split(Data.2$estimate, f = Data.2$variable)

sapply(vals, function(x) sapply(qt_vals, function(y) sum(x * y)))

     varA   VarB  VarC
pl0 0.140 18.198 3.843
pl1 0.140 18.198 3.843
pl2 3.406 19.918 6.769
pl3 4.460 19.962 6.957
pl4 0.140 18.198 3.843
pl5 4.460 19.962 6.957
pl6 4.460 19.962 6.957
pl7 3.406 19.918 6.769
pl8 4.460 19.962 6.957
pl9 0.140 18.198 3.843

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

...