Як я можу конвертувати дані у вигляді lat, lon, value у растровий файл за допомогою R?


40

У мене є набір даних із значення сітки на км у континентальній частині США. Стовпці "широта", "довгота" та "спостереження", наприклад:

"lat"    "lon"     "yield"
 25.567  -120.347  3.6 
 25.832  -120.400  2.6
 26.097  -120.454  3.4
 26.363  -120.508  3.1
 26.630  -120.562  4.4

або, як кадр даних R:

mydata <- structure(list(lat = c(25.567, 25.832, 26.097, 26.363, 26.63), 
lon = c(-120.347, -120.4, -120.454, -120.508, -120.562), 
yield = c(3.6, 2.6, 3.4, 3.1, 4.4)), .Names = c("lat", 
"lon", "yield"), class = "data.frame", row.names = c(NA, -5L))

(повний набір даних можна завантажити тут у форматі CSV )

Дані виводяться з моделі врожаю (призначена для використання) сіткою 30 км х 30 км (від Miguez et al 2012 ).

введіть тут опис зображення

Як я можу конвертувати їх у растровий файл із метаданими, пов'язаними з ГІС, такими як проекція карти?

В ідеалі файл був би текстовим файлом (ASCII?), Тому що я хотів би, щоб він був незалежним від платформи та програмного забезпечення.


Як CSV, це вже є «текстовим файлом» в ASCII. Крім того, оскільки він взагалі не використовує проекції, може бути мало релевантних метаданих, які слід додати (здебільшого дані). Не могли б ви бути трохи більш конкретними щодо того, який результат ви шукаєте і що ви маєте намір з цим зробити?
whuber

Я хотів би зробити так, щоб хтось міг використовувати ці дані з різним програмним забезпеченням для картографування (ArcGIS, Google Maps, Grass, R тощо), щоб полегшити повторне використання, наприклад, не вимагаючи додаткових кроків перетворення. На основі сторінки Вікіпедії у форматах файлів GIS я роблю висновок: 1) "растровий" файл повинен мати назви рядків із широтою та назвами стовпців довготи, як зображення, а також, що 2) метадані повинні містити географічну інформацію (місце розташування кута, покрита область за даними).
Абе

Це одна з найкращих посилань, на яку я натрапив на R та GIS. Дуже дякую! Чи можете ви надати ще один csv з lat та long з правильним proj4string? Я дуже це оціню.

@Nandini Не впевнений , що правильно proj4string, я підозрюю , Ламберт:proj +proj=lcc +lat_1=50.0 +lat_2=50.0 +units=km +lon_0=-145.5 +lat_0=1.0 . Я не впевнений, що ви запитуєте стосовно іншого файлу csv - чим він відрізнятиметься від того, на який пов’язаний у запитанні, або що буде спричинене прийнятою відповіддю?
Абе

для мене не працює! Я не знаю, що поставити на "x" та "y" to "координати (бали) = ~ x + y"

Відповіді:


44

Необхідно виконати кілька кроків:

  1. Ви кажете, що це звичайна сітка на 1 км, але це означає, що термін тривалості не є регулярним. Спочатку потрібно перетворити його на звичайну систему координат сітки, щоб значення X і Y регулярно розташовувались.

    а. Прочитайте його на R у вигляді кадру даних із стовпцями х, у, вихід.

    pts = read.table("file.csv",......)

    б. Перетворіть фрейм даних в SpatialPointsDataFrame за допомогою пакету sp і щось подібне:

    library(sp)
    library(rgdal)
    coordinates(pts)=~x+y

    c. Перетворіть у звичайну систему км, спочатку скажіть, що це CRS, а потім spTransform до місця призначення.

    proj4string(pts)=CRS("+init=epsg:4326") # set it to lat-long
    pts = spTransform(pts,CRS("insert your proj4 string here"))

    г. Скажіть R, що це сітка:

    gridded(pts) = TRUE

    У цей момент ви отримаєте помилку, якщо ваші координати не лежать на хорошій регулярній сітці.

  2. Тепер використовуйте растровий пакет для перетворення в растр і встановіть його CRS:

    r = raster(pts)
    projection(r) = CRS("insert your proj4 string here")
  3. Тепер подивіться:

    plot(r)
  4. Тепер запишіть його як файл geoTIFF, використовуючи растровий пакет:

    writeRaster(r,"pts.tif")

Цей geoTIFF має бути читабельним у всіх основних пакетах ГІС. Очевидною частиною, яка тут відсутня, є рядок proj4, до якої потрібно конвертувати: це, мабуть, буде якась система відліку UTM. Важко сказати без додаткових даних ...


+1 Дякуємо, що виклали робочий процес. Зауважте, що дані доступні за посиланням, поданим у запитанні: подивіться. Ви побачите, на жаль, деякі ваші припущення щодо них невірні. (Зокрема, я полював на будь-яку документацію про проекцію, яку використовували для створення сітки, але не знайшов жодної. І це дивна проекція, як ви бачите, побудувавши точки.)
whuber

Це дуже близько до того, щоб бути системою UTM, але жоден із тих, кого я намагався, не є достатньо близьким до звичайної сітки для R, щоб передати їх сітку. Я наполовину спокусився переглядати всю R-базу даних epsg ....
Spacedman

Це було б справжньою формою екскурсії, якби ви змогли відкрити проекцію саме так! Головне - знайти ефективний та ефективний критерій, щоб визначити, коли ці 7000+ точок досить близькі до того, щоб лежати на звичайній сітці (адже можливо, вони взагалі не можуть сформувати ідеальну сітку в будь-якій стандартній проекції). Для швидкого пробігу по базі даних має бути достатньо порівняти невелику кількість відстаней, наприклад відстань схід-захід у північній частині сітки та відстань схід-захід у південній частині. Це повинно швидко усунути переважну більшість кандидатів.
whuber

3
Я пробіг усі проекції (за замовчуванням), які підтримує Mathematica 8. Він знайшов проекцію, в якій точки справді падають на сітку: Зона штату Аляска (1983) Зона 10! Це конформальна проекція Ламберта. Я вважаю, що це EPSG 26940 . Якщо ви модифікуєте це за центром приблизно на довготі -106, точки утворюють досить гарну сітку.
whuber

1
Абе, ти маєш на увазі читати веб-сторінку? Це було r = Import[ "https://ebi-forecast.igb.illinois.edu/bety/miscanthusyield.csv", "Data"];. Після цього ви можете отримати швидкий графік балів за допомогою data = Rest[r]; ListPlot[data[[;; , {3, 2}]]](або ListPointPlot3D[data[[;; , {3, 2, 4}]]]). Для повторних проекцій почніть з довідки GeoGridPosition, а потім зробіть кілька розумних здогадок та перехресних посилань, щоб з’ясувати, що відбувається :-). BTW, @ пояснення Spacedman дійсно актуальне: метричне спотворення від 25 до 49 градусів дорівнює cos (25) / cos (49) = 1,38; це суттєво.
whuber

29

З часу останнього відповіді на питання існує набагато простіше рішення за допомогою функції пакету растрових пакетів, rasterFromXYZяка інкапсулює всі необхідні кроки (включаючи специфікацію рядка CRS).

library(raster)
rasterFromXYZ(mydata)

1
Вибачте невтомного @Spacedman, який мені часто допомагав, але я вважаю, що ця відповідь заслуговує на спадщину веселого зеленого галочки.
геотеорія

@geotheory Я вибрав би цю відповідь, її чудова функція, але, схоже, це дуже повільно в наборі даних, який я використовую (пов'язане з оп.)
Abe

1
... насправді він захлинувся, тому що він зайняв мій файл ~ 400 КБ і створив файл, /tmp/який був ~ 19 Гб, коли мені не вистачало місця на диску.
Абе

Напевно, там десь процес n-квадрата. Можливо, ви зможете згрупувати дані очок за широкою сіткою, розчленовуйте кожну групу окремо, а потім отримайте merge()результати разом.
геотеорія

З усією повагою, але ця відповідь є набагато кращою, ніж відповідь Spacedman.
Привид
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.