У меня есть фрейм данных, который содержит 7 столбцов.
str(df)
'data.frame': 8760 obs. of 7 variables:
$ G1_d20_2014.SE1_ : num 25.1 25.1 25 25 25.1 ...
$ G1_d20_2014.SE4_ : num 42.4 42.3 42.3 42.3 42.3 ...
$ G1_d20_2014.SE7_ : num 34.4 34.4 34.4 34.4 34.4 ...
$ G1_d20_2014.SE22_: num 42.5 42.4 42.3 42.4 42.3 ...
$ G1_d20_2014.SE14_: num 52.5 52.5 52.5 52.5 52.4 ...
$ G1_d20_2014.SE26 : num 40.8 40.8 40.8 40.8 40.8 ...
Каждый столбец представляет уникальный датчик, а столбцы содержат данные измерений от датчиков. Некоторые столбцы содержат пропущенные значения. Я хочу заполнить пробелы в данных в каждом столбце с помощью линейной регрессии. Я уже сделал это вручную, но есть одно очень важное условие, и я ищу функцию, которая делает это самостоятельно, так как это займет слишком много времени для всех столбцов. Вот условие: Допустим, G1_d20_2014_SE1 содержит недостающие данные. Затем я хочу заполнить пробелы в данных от этого датчика полным набором данных от другого датчика с самым высоким коэффициентом корреляции.
Вот как я сделал это вручную:
Я создал функцию, которая создает индикаторную переменную. Переменная-индикатор становится равной 1, если значение не равно NA, и 0, если NA. Затем я добавил эту переменную в качестве столбца в набор данных:
Indvar <- function(t) {
x <- dim(length(t))
x[which(!is.na(t))] = 1
x[which(is.na(t))] = 0
return(x)
}
df$I <- Indvar(df$G1_d20_2014.SE1_)
Затем я посмотрел, между каким датчиком и датчиком 1 коэффициент корреляции самый высокий (в этом случае коэффициент корреляции самый высокий между SE1 и SE14). Затем я вычислил линейную регрессию, взял из нее уравнение и поместил его в цикл for, который заполняет значения NA в соответствии с уравнением всякий раз, когда индикаторная переменная равна 0:
lm(df$G1_d20_2014.SE1_ ~ df$G1_d20_2014.SE14_, data = df)
for (i in 1:nrow(df)) {
if (df$I[i] == 0)
{
df$G1_d20_2014.SE1_[i] = 8.037 + 0.315*df$G1_d20_2014.SE14_[i]
}
}
Это прекрасно работает, но это занимает слишком много времени, потому что у меня много фреймов данных, которые выглядят как тот, что в посте.
Я уже пробовал использовать impute_lm из пакета simputation, но, к сожалению, он, похоже, не заботится о том, где корреляция самая высокая, прежде чем заполнять пробелы в данных. Вот что я написал:
impute_fun <- impute_lm(df,
formula = SE1_ + SE4_ ~ SE14_ + SE26)
Как я писал SE14_ + SE26_
, я проверил, использует ли он значения из SE14 для вменения значений в SE1, но он этого не делает, так как результат отличается от моего ручного результата.
Есть ли функция, которая делает то, что я хочу? Я очень расстроен, потому что я искал это уже более 2 недель. Я был бы очень признателен за помощь!
ИЗМЕНИТЬ/Ответить на @jay.sf
Итак, я попытался сделать из него функцию (см. Ниже), но есть кое-что, с чем я борюсь:
Я не знаю, как указать в функции, что я хочу сделать это для каждого столбца, и что она удаляет имя того датчика, который я хочу заполнить, из sapply(c("SE1_", "SE2_", . ..) Потому что, очевидно, если я сделаю это для SE1_, а SE1_ все еще находится в коде, корреляция будет равна 1, и ничего не произойдет. Теперь, как вы можете видеть, это также проблематично для остальной части кода, например, в строке cor( df$SE1_, df[, x], use = "complete.obs")), как здесь написано df$SE1_. То же самое для строки df$SE1_imp ‹- .... Конечно, я мог бы просто удалить датчик из кода sapply(...), чтобы не возникало первой проблемы. Мне просто интересно, есть ли более приятный способ сделать это. То же самое для частей df$SE1_, если я хочу присвоить значения для SE2_, тогда мне придется изменить df$SE1_ на df$SE2_ и так далее.
Я попытался запустить такой код (но без SE1_ в sapply(...) конечно) и получил ошибку: Ошибка в df[, x] : неправильное количество измерений. Любые идеи, как решить эти проблемы?
impFUN <- function(df) {
corr <- sapply(c("SE1_", "SE2_", "SE4_", "SE5_","SE6_",
"SE7_", "SE12_", "SE13_","SE14_", "SE15_",
"SE16_", "SE22_","SE23", "SE24", "SE25",
"SE26", "SE33", "SE34", "SE35", "SE36",
"SE37", "SE46", "SE51", "SE52", "SE53",
"SE54", "SE59", "SE60", "SE61", "SE62",
"SE68", "SE69", "SE70", "SE71", "SE72",
"SE73","SE74", "SE82", "SE83", "SE84",
"SE85", "SE86", "SE87", "SE99","SE100",
"SE101", "SE102", "SE103","SE104",
"SE106", "SE107","SE121"), function(x)
cor(df$SE1_, df[, x], use = "complete.obs"))
imp.use <- names(which.max(corr))
regr.model <- lm(reformulate(imp.use, "SE1_"))
df$SE1_imp <-
ifelse(is.na(df$SE1_), lm.cf[1] + df[[imp.use]]*lm.cf[2], df$SE1_)
}
df$G1_d20_2014_
на основеdf$G1_d20_2014.SE14
, чтобы заполнить отсутствующие значения дляdf$G1_d20_2014.SE1
. Вместо того, чтобы предсказывать каждую отсутствующую точку данных отдельно, почему бы не векторизовать ее? Например,mod <- lm(df$G1_d20_2014.SE1_[df$I==1] ~ df$G1_d20,2014.SE14_[df$I==1]); df$G1_d20_2014.SE1[df$I==0] <- predict(mod, df$G1_d20_2014.SE14[df$I==0])
- person koenniem   schedule 12.05.2020