2016-08-29 8 views
0

У меня есть целочисленный растровый результат классификации. Теперь я хочу заменить классы значениями float из фрейма данных, то есть растровым классом 1 = 0.321; Класс 2 = 0,322; Класс 3 = 3.211. dataframe имеет много столбцов, и я хочу, чтобы заменить классы для различных случаев:Замените классы растра на значения из data.frame в R

Class C  N  .... 
1 0.321 0.001 
2 0.232 0.012 
3 3.211 0.021 

Есть ли способ сделать это удобно, как слияние data.frame в растр? Мне нужно умножить полученный растровый рисунок на другой растровый, чтобы генерировать мои выходы.

Это метаданные растрового файла:

> LCC 
class  : RasterLayer 
dimensions : 3296, 3711, 12231456 (nrow, ncol, ncell) 
resolution : 2, 2 (x, y) 
extent  : 514151.8, 521573.8, 7856419, 7863011 (xmin, xmax, ymin, ymax) 
coord. ref. : +proj=utm +zone=55 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
data source : /home/..../Raster.tif 
names  : Raster 
values  : 0, 255 (min, max) 

`

и это метаданные о dataframe:

>str(SOC) 
data.frame': 11 obs. of 57 variables: 
    $ class    : int 8 9 5 6 7 4 1 2 3 0 ... 
    $ area    : int 3135964 3941744 9048672 8564312 11568512  
    $ pixel_count  : int 783991 985436 2262168 2141078 2892128 ... 
    $ percent_area  : Factor w/ 11 levels "0.17%","17.50%",..: 9 11 3 2 
    $ label.x   : Factor w/ 11 levels "Barren",..: 5 8 2 
    $ label.y   : Factor w/ 8 levels "Barren",..: 4 7 2 
    $ n     : int 7 4 4 3 4 1 1 NA NA NA ... 
    $ mean_C_100cm  : num 25.8 29 21.3 34.8 31.9 ... 
    $ mean_N_100cm  : num 0.469 0.514 0.503 0.621 0.34 ... 
.... 

`

+0

Является ли желаемый вывод поплавковым растром (или кирпичом растров) со значениями, отображаемыми на столбцы C, N и т. Д.? – aichao

+0

Если я правильно понимаю вас, тогда да. – mace

ответ

1

Если я понимаю, что вы хотите правильно, тогда вы можете назначить значения растра, используя значения в столбце в df по:

inp[] <- df[inp[],"C"] 

где df является, как вы определили и inp является целым числом растр со значениями от 1 до 3.

Например:

library(raster) 
set.seed(42) ## for reproducibility 

inp <- raster(ncol=10, nrow=10) ## example is small, yours will be large 
inp[] <- floor(runif(ncell(inp), min=1, max=4)) ## generate integers from 1 to 3 
inp[] 
## [1] 3 3 1 3 2 2 3 1 2 3 2 3 3 1 2 3 3 1 2 2 3 1 3 3 1 2 2 3 2 3 3 3 2 3 1 3 1 1 3 2 2 2 1 3 2 3 3 2 
## [49] 3 2 2 2 2 3 1 3 3 1 1 2 3 3 3 2 3 1 1 3 3 1 1 1 1 2 1 3 1 2 2 1 2 1 2 2 3 2 1 1 1 1 3 1 1 3 3 3 
## [97] 1 2 3 2 

df <- data.frame(Class=c(1,2,3), C=c(0.321,0.232,3.211), N=c(0.001,0.012,0.021)) ## your df 

## generate output raster the same size as inp 
out <- raster(ncol=10,nrow=10) 
## map values of out to values in column C of df 
## can overwrite inp here if desired, but for example we want to keep inp 
## for following steps 
out[] <- df[inp[],"C"] 
out[] 
## [1] 3.211 3.211 0.321 3.211 0.232 0.232 3.211 0.321 0.232 3.211 0.232 3.211 3.211 0.321 0.232 3.211 
## [17] 3.211 0.321 0.232 0.232 3.211 0.321 3.211 3.211 0.321 0.232 0.232 3.211 0.232 3.211 3.211 3.211 
## [33] 0.232 3.211 0.321 3.211 0.321 0.321 3.211 0.232 0.232 0.232 0.321 3.211 0.232 3.211 3.211 0.232 
## [49] 3.211 0.232 0.232 0.232 0.232 3.211 0.321 3.211 3.211 0.321 0.321 0.232 3.211 3.211 3.211 0.232 
## [65] 3.211 0.321 0.321 3.211 3.211 0.321 0.321 0.321 0.321 0.232 0.321 3.211 0.321 0.232 0.232 0.321 
## [81] 0.232 0.321 0.232 0.232 3.211 0.232 0.321 0.321 0.321 0.321 3.211 0.321 0.321 3.211 3.211 3.211 
## [97] 0.321 0.232 3.211 0.232 

## can create a brick and add layers that map values from N column of df 
out.brick <- brick(x=out) 
out[] <- df[inp[],"N"] 
out.brick <- addLayer(out.brick, out) 
out.brick[[2]][] 
## [1] 0.021 0.021 0.001 0.021 0.012 0.012 0.021 0.001 0.012 0.021 0.012 0.021 0.021 0.001 0.012 0.021 
## [17] 0.021 0.001 0.012 0.012 0.021 0.001 0.021 0.021 0.001 0.012 0.012 0.021 0.012 0.021 0.021 0.021 
## [33] 0.012 0.021 0.001 0.021 0.001 0.001 0.021 0.012 0.012 0.012 0.001 0.021 0.012 0.021 0.021 0.012 
## [49] 0.021 0.012 0.012 0.012 0.012 0.021 0.001 0.021 0.021 0.001 0.001 0.012 0.021 0.021 0.021 0.012 
## [65] 0.021 0.001 0.001 0.021 0.021 0.001 0.001 0.001 0.001 0.012 0.001 0.021 0.001 0.012 0.012 0.001 
## [81] 0.012 0.001 0.012 0.012 0.021 0.012 0.001 0.001 0.001 0.001 0.021 0.001 0.001 0.021 0.021 0.021 
## [97] 0.001 0.012 0.021 0.012 

Надеюсь, что это помогает.

+0

Спасибо, кажется, работает в примере, но не с моими исходными данными, которые сильно искажаются. Может быть, потому, что значения в кадре данных хранятся как числовые? – mace

+0

@mace вы можете представить пример разумного размера относительно того, почему ваши данные сильно искажены? Возможно, ваши данные имеют коэффициенты вместо целых чисел. Можете ли вы предоставить результат из растра (т., просто распечатайте растровую переменную для вывода ее метаданных) и укажите вывод из 'str (df)' в своем сообщении (т. е. отредактируйте сообщение вместо ответа на этот комментарий)? – aichao

+0

Хорошо, спасибо за помощь. Я понял, какое рабочее решение я опубликую позже. – mace

2

Для этого есть функция (subs).

Пример данных (после achaio)

library(raster) 
inp <- raster(ncol=10, nrow=10) 
set.seed(42) 
inp[] <- sample(3, ncell(inp), replace=TRUE) 
df <- data.frame(Class=c(1,2,3), C=c(0.321,0.232,3.211), N=c(0.001,0.012,0.021)) 

Для замены идентификатора с "C", вы можете сделать

x <- subs(inp, df, by=1, which=2) 

Или, чтобы получить как "C" и "N", сделать

y <- subs(inp, df, by=1, which=2:3) 

Действительно, как булава указывает, вы можете также использовать reclassify (но только для одной переменной в момент времени)

z <- reclassify(inp, as.matrix(df)[, 1:2]) 
+0

Спасибо, Роберт, это самое элегантное решение. – mace

+0

Однако, используя реклассификацию, мир быстрее в большом файле (100 МБ). – mace

0

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

library(raster) 
set.seed(42) ## for reproducibility 

inp <- raster(ncol=10, nrow=10) ## example is small, yours will be large 
inp[] <- floor(runif(ncell(inp), min=1, max=4)) ## generate integers from 1 to 3 

df <- data.frame(Class=c(1,2,3), C=c(10.321,1.232,0.211), N=c(0.001,0.012,0.021)) ## your df 

## generate output raster the same size as inp 
out <- raster(ncol=10,nrow=10) 


#### here I generate a matrix that defines the 
#### reclassification with an upper and lower limit 

mtr <- data.frame(cl_low =df$Class -1, cl_high = df$Class, C =df$C) 
data.matrix(mtr) ### use as matrix 

# now reclassify using the matrix and transfer the result in a raster brick 

out <- reclassify(inp, rcl=mtr) 
out.brick <- brick(x=out) 

# now the same can be done for next variable 
mtr <- data.frame(cl_low =df$Class -1, cl_high = df$Class, N =df$N) 
data.matrix(mtr) 
out <- reclassify(inp, rcl=mtr) 
out.brick <- addLayer(out.brick, out) 
[email protected]