#r
#r
Вопрос:
Вот пример данных:
set.seed(123)
covar1 <- matrix(sample(c(NA, 1:3), 10, replace = TRUE), 10,1)
covar2 <- matrix(sample(c(NA, 1:3), 10, replace = TRUE), 10,1)
covar3 <- matrix(sample(c(NA, 1:3), 10, replace = TRUE), 10,1)
covar4 <- matrix(sample(c(NA, 1:3), 10, replace = TRUE), 10,1)
covar5 <- matrix(sample(c(NA, 1:3), 10, replace = TRUE), 10,1)
df <- as.data.frame(cbind(covar1,covar2,covar3,covar4,covar5))
names(df) <- c("covar1","covar2","covar3","covar4","covar5")
И это мои 3 модели с параметрами, каждая из которых соответствует ковариации, как в df
model0 <- data.frame(covar1=4,covar5=7)
model1 <- data.frame(covar1=2,covar3=5,covar4=3)
model2 <- data.frame(covar1=2,covar2=5,covar3=3,covar5=7)
Теперь я хотел бы выбрать model0-2 и предварительно умножить с соответствующей строкой из df
. Строки df, которые не соответствуют критериям соответствия, дадут NA
.
Предполагается всегда использовать самую длинную модель из 3 доступных. Итак, если строка соответствует 4-ковариационной модели = model2, эта df
строка должна быть предварительно умножена на model2, если совпадения нет, следует попробовать model1 или model0 в меньших размерах.
Желаемый результат:
covar1 covar2 covar3 covar4 covar5 Output Model
1 NA 2 3 NA NA NA
2 1 NA 2 2 2 18 m1 # (1*2) (2*5) (2*3)=18
3 3 1 2 1 1 21 m2 # (1*3) (1*5) (3*2) (7*1)=21
4 NA 1 NA 3 2 NA # (1*2) (2*5) (2*3)=18
..
..
Сейчас я не собираюсь писать, что я пробовал, поскольку это включало бы еще больше информации, которая обычно не нравится пользователям SO. Для чего-то подобного там может быть даже package. Любой намек или помощь очень ценятся.
Ответ №1:
Прежде всего, при создании data.frame не используйте эту комбинацию as.data.frame
/ cbind
. Просто используйте
df <- data.frame(covar1,covar2,covar3,covar4,covar5)
Это также приведет к соответствующей настройке имен. Я не уверен, где люди используют cbind
метод, но это не очень хорошая привычка.
В любом случае, перейдем к вашей реальной проблеме. Было бы лучше хранить ваши модели в списке (от самого длинного к самому короткому). Это упростит обработку
models <- list(m2=model2, m1=model1, m0=model0)
Теперь мы можем просмотреть фрейм данных и посмотреть, какая модель имеет наибольшее перекрытие с не пропущенными значениями ковариации. Сначала я вычисляю перекрытие, а затем выбираю наилучшую модель для каждой строки
mmatch <- sapply(models, function(m) rowSums(!is.na(df[,names(m)]))/ncol(m))
wmodel <- apply(mmatch,1,which.max)
Теперь, когда я знаю лучшую модель для каждой группы (ну, в частности, ее индекс в списке моделей) Я разделю data.frame на основе наилучшего соответствия, выполню умножение, а затем объединю данные.
out<-unsplit(Map(function(m,d,n)
{cbind(d, Output=rowSums(d[,names(m)]*m[1,,drop=T], na.rm=T),
Model=n, stringsAsFactors=F)
},
models,
split(df, wmodel),
names(models)),
wmodel)
Это вернет
covar1 covar2 covar3 covar4 covar5 Output Model
1 1 3 3 3 NA 26 m1
2 3 1 2 3 1 24 m2
3 1 2 2 2 1 25 m2
4 3 2 3 3 1 32 m2
5 3 NA 2 NA NA NA m1
6 NA 3 2 1 NA NA m1
7 2 NA 2 3 NA 23 m1
8 3 NA 2 NA 1 19 m0
9 2 1 1 1 1 19 m2
10 1 3 NA NA 3 25 m0
Я не уверен, что желаемый результат, который вы показали, на самом деле использовал указанное вами начальное значение, потому что я получил разные значения.