Why am I getting Error in ms[i, ] : subscript out of bounds ?

This is what I am trying to do, to create a spectral profiles for landcover classes. I want to plot every landcover spectral and I have 7 classes

I have landsat raster, a rasterbrick =img with 7 bands

img
class : RasterBrick
dimensions : 1062, 1980, 2102760, 7 (nrow, ncol, ncell, nlayers)
resolution : 30, 30 (x, y)
extent : 891690, 951090, 7999140, 8031000 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=34 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-138,-105,-289,0,0,0,0 +units=m +no_defs
source : memory
names : B1, B2, B3, B4, B5, B6, B7
min values : -109.0, 0.0, 91.0, 101.0, -50.0, -13.0, 23.5
max values : 2960.0, 3176.0, 4041.0, 4897.0, 6150.5, 7883.0, 7025.0

I have a spatialpointdataframe =trainData_crs_utm

trainData_crs_utm
class : SpatialPointsDataFrame
features : 114
extent : 894670.5, 940963.3, 7954040, 8026976 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=34 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-138,-105,-289,0,0,0,0 +units=m +no_defs
variables : 3
names : ForestID, PlotType, Class
min values : Chobe001, closedforest, 1
max values : Chobe104, water, 7

I extracted each Landsat band pixel values for each point using extract
dfAll<-raster::extract(x=img,y=trainData_crs_utm, method="bilinear",df=T)

head(dfAll)
B1 B2 B3 B4 B5 B6 B7 class
1 445.0 637.0 993.0 1197.0 2679.0 3387.0 2409.0 1
2 525.0 636.0 948.0 1078.0 2613.0 3256.0 2517.0 1
3 604.0 733.0 1049.0 1229.0 3377.0 3504.0 2891.0 1
4 490.0 583.0 954.0 1359.0 3113.0 3742.0 2886.0 1
5 216.0 292.0 535.0 620.0 2274.0 2327.0 1299.0 1

This is the bit where I have a problem. I am getting an error once I run the for loop, the error is specifically in the last code of the for loop: Error in [<-(*tmp*, i, , value = colMeans(x)) : no 'dimnames' attribute for array

create an empty data.frame to store the mean spectra

df <- round(dfAll)
ms <- matrix(NA, nrow = length(unique(trainData_crs_utm$PlotType)), ncol = nlayers(img))

for (i in unique(trainData_crs_utm$PlotType)){
x <- df[trainData_crs_utm$PlotType==i,]
ms[i,] <- colMeans(x)

}

Error in [<-(*tmp*, i, , value = colMeans(x)) :
no 'dimnames' attribute for array

This is the rest of my code of what I am trying to execute if for loop worked, Can someone be able to tell why I am getting this error?

Specify the row- and column names

rownames(ms) <- unique(trainData_crs_utm$Class)
colnames(ms) <- names(img)

We will create a vector of color for the land use land cover classes and will resuse it

mycolor <- c('cyan', 'darkgreen', 'yellow', 'burlywood', 'darkred', 'darkgray', 'blue')

First create an empty plot

plot(1, ylim=c(300, 4000), xlim = c(1,7), xlab = "Bands", ylab = "Reflectance", xaxt='n')

Custom X-axis

axis(1, at=1:7, lab=colnames(ms))

add the other spectra

for (i in 1:nrow(ms)){
lines(ms[i,], type = "o", lwd = 3, lty = 1, col = mycolor[i])
}

i is one of these unique(trainData_crs_utm$PlotType) and you are trying to use it as a matrix index. I think R is telling you that you can't use i to index ms[,]. And please please please tidy up the formatting of your question. Three little backticks is all it takes.

Maybe you mean this.

plottypes <- unique(trainData_crs_utm$PlotType)
for (i in seq_along(plottypes )){
  x <- df[trainData_crs_utm$PlotType == plottypes[i], ]
  ms[i, ] <- colMeans(x)
}

Hi, and welcome!

Thanks for posting the code. It is always helpful, though, to use a reproducible example, called a reprex.

Although df_All is easy enough to replicate by hand by cutting and pasting into a csv then

library(tidyverse) # interactive session
df_All <- read.csv("~/Desktop/dfAll.csv", header = TRUE)
df_All
#>    B1  B2   B3   B4   B5   B6   B7 class
#> 1 445 637  993 1197 2679 3387 2409     1
#> 2 525 636  948 1078 2613 3256 2517     1
#> 3 604 733 1049 1229 3377 3504 2891     1
#> 4 490 583  954 1359 3113 3742 2886     1
#> 5 216 292  535  620 2274 2327 1299     1

Created on 2019-11-18 by the reprex package (v0.3.0)

img and trainData_crs_utm aren't, and they are numeric values that are used in the cast to ms, and it's uncertain what a good guess would be. But I'll pick numbers out of a hat.

An aside: df is the name of a built in function:

df
#> function (x, df1, df2, ncp, log = FALSE) 
#> {
#>     if (missing(ncp)) 
#>         .Call(C_df, x, df1, df2, log)
#>     else .Call(C_dnf, x, df1, df2, ncp, log)
#> }
#> <bytecode: 0x7fad326c3758>
#> <environment: namespace:stats>

Created on 2019-11-18 by the reprex package (v0.3.0)

and it's good practice to avoid using it for an assignment result; my_df or even df. is preferable.

Aside: df <- round(dfAll) doesn't do anything.

library(tidyverse) # interactive session
df_All <- read.csv("~/Desktop/dfAll.csv", header = TRUE)
df_All == round(df_All)
#>        B1   B2   B3   B4   B5   B6   B7 class
#> [1,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE  TRUE
#> [2,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE  TRUE
#> [3,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE  TRUE
#> [4,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE  TRUE
#> [5,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE  TRUE

On to the cast.

Created on 2019-11-18 by the reprex package (v0.3.0)

library(tidyverse) # interactive session
df_All <- read.csv("~/Desktop/dfAll.csv", header = TRUE)
ms <- matrix(NA, nrow = 7, ncol = 7)
ms
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,]   NA   NA   NA   NA   NA   NA   NA
#> [2,]   NA   NA   NA   NA   NA   NA   NA
#> [3,]   NA   NA   NA   NA   NA   NA   NA
#> [4,]   NA   NA   NA   NA   NA   NA   NA
#> [5,]   NA   NA   NA   NA   NA   NA   NA
#> [6,]   NA   NA   NA   NA   NA   NA   NA
#> [7,]   NA   NA   NA   NA   NA   NA   NA

Created on 2019-11-18 by the reprex package (v0.3.0)

It turns out that any nrow or ncol will have the same problem: all colMeans will be identically NA

library(tidyverse) # interactive session
df_All <- read.csv("~/Desktop/dfAll.csv", header = TRUE)
ms <- matrix(NA, nrow = 7, ncol = 7)
colMeans(ms)
#> [1] NA NA NA NA NA NA NA

Created on 2019-11-18 by the reprex package (v0.3.0)

Fix this and supply a reprex if you hit a bump again.

Finally, should this be homework, see the FAQ

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.