Создайте вектор для k-складок (ID указывает c) в R - PullRequest
0 голосов
/ 05 мая 2020

Я пробовал много чего, но все закончилось сообщениями об ошибках и странными вещами. В настоящий момент я использую функцию SurvSL, но я хочу немного настроить ее под свои конкретные потребности c. Вот полная функция:

#function to compute k-fold cross-validated concordance index for Lasso-Cox, Ridge-Cox, EN-Cox
  c_indexCv_combined1 = function(data,k){
  y_dat = Surv(data$obs.time,data$status)
  set.seed(1)
  folds = sample(rep(1:k, length.out = nrow(data)))
  prediction_lasso = c()
  prediction_ridge = c()
  prediction_net = c()
  index =c()
  for (j in 1:k){
    idx = which(folds==j)
    train = data[-idx,]
    test = data[idx,]
    y_train = Surv(train$obs.time, train$status)
    y_test = Surv(test$obs.time,test$status)
    x = model.matrix(~., data[,-c(1,2)])
    fit_lasso = glmnet(x[-idx,],y_train, family="cox", alpha=1)
    cvFit_lasso = cv.glmnet(x[-idx,],y_train, family="cox", alpha=1)
    pred_lasso = predict(fit_lasso,x[idx,], s=cvFit_lasso$lambda.min, type="link") 
    fit_ridge = glmnet(x[-idx,],y_train, family="cox", alpha=0)
    cvFit_ridge = cv.glmnet(x[-idx,],y_train, family="cox", alpha=0)
    pred_ridge = predict(fit_ridge,x[idx,], s=cvFit_ridge$lambda.min, type="link") 
    fit_net = glmnet(x[-idx,],y_train, family="cox", alpha=0.5)
    cvFit_net = cv.glmnet(x[-idx,],y_train, family="cox", alpha=0.5)
    pred_net = predict(fit_net,x[idx,], s=cvFit_net$lambda.min, type="link") 
    index = c(index,idx)
    prediction_lasso = c(prediction_lasso, pred_lasso)
    prediction_ridge = c(prediction_ridge, pred_ridge)
    prediction_net = c(prediction_net, pred_net)
  }

  Match = match(seq(nrow(data)), index)
  prediction_lasso = prediction_lasso[Match]
  prediction_ridge = prediction_ridge[Match]
  prediction_net = prediction_net[Match]
  c_lasso = survConcordance(y_dat~prediction_lasso)$concordance
  c_ridge = survConcordance(y_dat~prediction_ridge)$concordance
  c_net = survConcordance(y_dat~prediction_net)$concordance
  final_pred = cbind(prediction_lasso, prediction_ridge, prediction_net)
  return(list(pred = final_pred, c_index=c(c_lasso, c_ridge, c_net)))
}

Теперь мне нужно изменить эту часть:

folds = sample(rep(1:k, length.out = nrow(data)))

складок становится вектором с 1459-кратным числом от 1 до 5, так что я могу "сложить" мои 1459 наблюдений соответственно (в 5 групп по k = 5). Однако в моих данных есть переменная "ID". В большинстве случаев это уникальный номер. Но иногда бывают двойные / тройные. Очень важно, чтобы одни и те же идентификационные номера получали одинаковый номер сгиба (и чтобы у меня не было одного и того же идентификатора в двух разных сгибах). У меня 1459 наблюдений и 1240 различных «ID». Если мне нужно 5 складок (k), должно быть (1240/5 =) 248 различных идентификационных номеров на каждую складку.

Кто-нибудь знает классную / простую функцию для управления этим? После того, как я много дурачился в R, я начинаю опасаться, что мне придется создать этот вектор вручную для 1459 наблюдений ...

Заранее спасибо!

1 Ответ

0 голосов
/ 05 мая 2020

Вы можете сначала выбрать уникальные идентификаторы, а затем сопоставить строки. Пример:

k <- 5
set.seed(1)
samplepool <- paste0("ID_", sprintf("%04d", 1:1240))
df <- data.frame(idx=1:1459, 
    ID=sort(c(sample(samplepool, (1459-1240), replace = TRUE), samplepool)))
folds <- sample(rep(1:k, length.out = length(unique(df$ID)))) 
folds <- folds[match(df$ID, unique(df$ID))]

Создано 05.05.2020 с помощью пакета REPEX (v0.3.0)

Итак, в вашем коде предполагая переменную ID ID, вы должны заменить

folds = sample(rep(1:k, length.out = nrow(data)))

на

folds = sample(rep(1:k, length.out = length(unique(data$ID))))
folds = folds[match(data$ID, unique(data$ID))] 
...