[GRASS-user] grass command to subset the columns of a vector

Micha Silver tsvibar at gmail.com
Thu Feb 10 00:45:23 PST 2022


On 09/02/2022 15:56, Bernardo Santos via grass-user wrote:
> Dear Markus
>
> Thanks for your answer. I thought about v.db.dropcolumn earlier. 
> However, I am trying to include this within a function, following a 
> workflow in which the input vector might have columns with different 
> names, in which case it would be good to be able to select the ones to 
> keep instead of the ones to remove.
> For instance, let's say I want to be able to provide either of the 
> following input vectors:
> - "vector1", with columns "a, b, c, d, e"
> - "vector2", with columns "j, a, k, f, e"
> Let's say I want to keep only "a" and "e".
>
> If I use v.db.dropcolumn, I'll have to first list the names of all 
> columns (maybe with v.db.select), then match all the column names that 
> I do not want to keep ("b, c, d" in the first case, "j, k, f" in the 
> second), then drop them with v.db.dropcolumn. I thought just selecting 
> which ones I want to keep would be simpler and more straightforward, 
> if there is a tool for that.
>
> So far I am doing a long step (I am creating a temporary vector to 
> avoid changing the input):
> 1) v.extract -t input=vector1 output=temp_vector (here I select only 
> the features, not attribute table)
> 2) v.db.addtable map=temp_vector columns=a,e (here I do not bother 
> with the names of the undesirable columns)
> 3) v.db.update map=temp_vector column=e value=1 (here I set a value 
> but I could take it from the original vector1)
>
> Following what you suggest, I could do:
> 1) g.copy vector=vector1,temp_vector
> 2) (find out a way to list the undesirable column names)


Here's a possible solution. (Somewhat clunky, but workable)

You can get the column names using v.info -c, then grep out the column 
names you want to keep. Then loop thru the column names that are left 
and do v.db.dropcolumn for each.


i.e.:

# I have a vector "terraces" with 4 columns.

v.info -c terraces
Displaying column types/names for database connection of layer <1>:
INTEGER|cat
INTEGER|OBJECTID
DOUBLE PRECISION|Shape_Leng
INTEGER|Validated


#Keep only 2: "cat" and "Validated"

g.copy vect=terraces,terraces_tmp
Copying vector <terraces at Avdat> to current mapset as <terraces_tmp>


# Get a list of columns to drop

to_drop=`v.info -c terraces_tmp | cut -d'|' -f2 | grep -E -v 'Validate|cat'`
Displaying column types/names for database connection of layer <1>:


echo $to_drop
OBJECTID Shape_Leng


# Loop thru columns to drop and run v.db.dropcolumn on each

for col in $to_drop; do v.db.dropcolumn terraces_tmp col=${col}; done


# Result

v.info -c terraces_tmp
Displaying column types/names for database connection of layer <1>:
INTEGER|cat
INTEGER|Validated


HTH,

Micha


> 3) v.db.dropcolumn columns=list_undesidable_columns
>
> Neither of the solutions is so straightforward, that's why I thought 
> there should be (or could be) another way.
> In R, for instance, I can easily subset columns of an sf object using 
> dplyr::select(vector1, a, e). I guess in PostGIS it is also possible 
> to do that with "SELECT statements", even though I am less skilled 
> there. It would be great to have a module in GRASS to do it as well...
>
> Best
> Bernardo
> Em quarta-feira, 9 de fevereiro de 2022 09:28:06 GMT+1, Markus Neteler 
> <neteler at osgeo.org> escreveu:
>
>
> Hi Bernardo,
>
> On Wed, Feb 9, 2022 at 1:39 AM Bernardo Santos via grass-user
> <grass-user at lists.osgeo.org> wrote:
> >
> > Dear list,
> >
> > Is there a GRASS GIS command (maybe a v.db.* one) to subset, in a 
> single command, the columns of a vector?
> >
> > What I have: vector "vect" with 5 columns "a, b, c, d, e" in the 
> attribute table
> > What I want: vector "vect_sub" with only, for instance, "a, c, e"
> >
> > I can use v.extract to subsample rows, but not columns. What is the 
> easiest way of doing that, what needing many commands (like creating 
> or copying the vector to a new one, creating a new attribute table, 
> then copying only the columns I want).
>
> Isn't this simply
>
> https://grass.osgeo.org/grass80/manuals/vector.html
> --> v.db.dropcolumn - Drops a column from the attribute table
> connected to a given vector map.
>     --> It offers single and multiple column dropping: 
> columns=name[,name,...]
>
>
> > I looked for that in the documentation but did not found it so easily.
>
>
> Please suggest where to improve the documentation.
>
> Markus
>
>
> _______________________________________________
> grass-user mailing list
> grass-user at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/grass-user

-- 
Micha Silver
Ben Gurion Univ.
Sde Boker, Remote Sensing Lab
cell: +972-523-665918



More information about the grass-user mailing list