Как применить пользовательскую функцию с несколькими параметрами для df по уровням факторов - PullRequest
0 голосов
/ 25 мая 2018

Для более подробной информации: у меня есть набор координат в широте / долготе, и я хочу добавить соответствующие UTM-координаты во фрейм данных или SpatialPointsDataFrame.Для этого я до сих пор написал функцию, которая делает это, сначала преобразовав df в SpatialPointsDataFrame, перепроектирует в UTM и записывает координаты во входной DF.

WGS2UTM <- function(df, WGS_coords){
    temp <- sp::SpatialPointsDataFrame(coords = WGS_coords, data = df, 
                                       proj4string = CRS("+proj=longlat 
                                       +ellps=WGS84 +datum=WGS84 +no_defs"))
    temp <- spTransform(temp, CRS(as.character(unique(temp@data$EPSG_UTM))))
    df$UTM_E <- sp::coordinates(temp)[,"x"]
    df$UTM_N <- sp::coordinates(temp)[,"y"]
    return(df)
}

Код EPSG, используемый для перепроектированияв функции содержится в DF как фактор.

Теперь к моему вопросу: так как мы часто имеем дело с местоположениями, распределенными по нескольким различным зонам UTM, я хотел бы иметь возможность применить вышеупомянутую функцию куровни факторов столбца EPSG_UTM.Я знаю, что семейство apply лучше всего использовать для такого рода операций, но я не могу понять это.Есть указатели?

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

Пересмотрите использование расширения фрейма данных в цикле, что приводит к чрезмерному копированию в памяти.Поскольку решение split() сработало, рассмотрите возможность создания списка фреймов данных с использованием by() (примерно эквивалентно split + lapply), а затем rbind всех фреймов данных за один вызов.

df_list <- by(data, data$EPSG_UTM, function(sub) WGS2UTM(sub, sub[,c("x","y")]))

coords_df <- do.call(rbind, df_list)

data.cbind <- cbind(data, coords_df)
0 голосов
/ 25 мая 2018

Что ж, похоже, я нашел альтернативу, хотя она включает цикл for, пару дополнительных строк и разбиение данных на список фреймов данных.

UTM = NULL

df_list <- split(data, data$EPSG_UTM)
  for (i in 1:length(df_list)){
    t <- WGS2UTM(df_list[[i]],data.frame(df_list[[i]])[,c("x","y")])
    UTM=rbind(UTM,t)
  }
data.cbind <- cbind(data,UTM)
...