Сейчас я пытаюсь преобразовать скрипт, который выполняет интерполяцию в объекте data.table (по группе), в функцию.
У меня есть данные в длинном формате, как в этом примере:
UniqueId Time Var1 Var2 Var3
1 Id1 0 10 "cat-a" 2
2 Id1 5 12 "cat-a" 4
3 Id1 10 14 "cat-a" 6
4 Id2 0 8 "cat-b" 3
5 Id2 10 16 "cat-b" 10
6 Id3 0 6 "cat-a" 4
7 Id3 10 9 "cat-a" 8
[...]
Как видите, количество записей для каждого UniqueId может отличаться. Я хочу извлечь все уникальные значения столбца «Время» и убедиться, что все UniqueIds имеют запись для каждого из них, выполнив линейную интерполяцию для переменных numeri c, а для факторов или строк, поскольку они не меняются с течением времени, я беру первое значение для каждого UniqueId и повторяю его n раз (где n = length (unique (Time))), в результате получается что-то вроде этого:
UniqueId Time Var1 Var2 Var3
1 Id1 0 10 "cat-a" 2
2 Id1 5 12 "cat-a" 4
3 Id1 10 14 "cat-a" 6
4 Id2 0 8 "cat-b" 3
5 Id2 5 12 "cat-b" 6.5
6 Id2 10 16 "cat-b" 10
7 Id3 0 6 "cat-a" 4
8 Id3 5 7.5 "cat-a" 6
9 Id3 10 9 "cat-a" 8
[...]
Как данные, над которыми я работаю, могут быть довольно большими (несколько Go), я решил использовать пакет data.table. Мой текущий код выглядит так:
Time.Common <- unique(MyData[, Time])
Time.Common <- Time.Common[order(Time.Common)]
MyData[, mapply(function(colVals, colName) {
if(colName == "Time"){ # If we are operating on the time column, we replace its values with those of Time.Common
return(Time.Common)
}
if(is.factor(colVals) | is.character(colVals)){ # If we are working on character or factor columns, we just repeat the value "length(Time.Common)" times
rep(colVals[1], length(Time.Common))}
else { # If it's a numeric column, we perform an interpolation
withCallingHandlers(approx(x = .SD[,Time],
y = colVals,
xout = Time.Common)$y,
warning = function(w){invokeRestart("muffleWarning")})
}
}, .SD, names(.SD), SIMPLIFY = FALSE), by = eval(expr = "UniqueId")] # The process is repeated for each unique key value
Этот код дает ожидаемый Результаты. Проблема в том, что когда я пытаюсь преобразовать в функцию, я не могу заставить ее работать, и, поскольку я не эксперт по data.table, я не понимаю, в чем проблема.
Вот функция:
interpolation <- function(Data,
UniqueKey = "UniqueId",
TimeCol = "Time",
InterMethod = "linear"){
# Recovering all unique values of the time column
Time.Common <- unique(Data[, get(TimeCol, inherits = F)])
Time.Common <- Time.Common[order(Time.Common)]
# Interpolating
Data[, mapply(function(colVals, colName) {
if(colName == TimeCol){
return(Time.Common)
}
if(is.factor(colVals) | is.character(colVals)){
rep(colVals[1], length(Time.Common))}
else {
withCallingHandlers(approx(x = .SD[,eval(parse(text = TimeCol))],
y = colVals,
xout = Time.Common,
method = InterMethod)$y,
warning = function(w){invokeRestart("muffleWarning")})
}
}, .SDcols = .SD, names(.SD), SIMPLIFY = FALSE), by = eval(parse(text = UniqueKey))]
}
Это практически тот же код, за исключением той части, где я передаю имена столбцов в качестве переменных, где я должен использовать eval(parse())
или get()
. Это функция не производит ce ошибок, когда я его использую, но также не выполняет интерполяцию (мои данные остаются без изменений). Может ли кто-нибудь помочь мне в этом и помочь найти мою ошибку?
Заранее спасибо!