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

Bernardo Santos bernardo_brandaum at yahoo.com.br
Thu Feb 10 02:06:22 PST 2022


 Hi Micha,
thanks for the suggestion, it solves my question on how to perform this middle step of listing the columns that do not match the intended ones. I'll use it for now! =)
BestB    Em quinta-feira, 10 de fevereiro de 2022 09:45:29 GMT+1, Micha Silver <tsvibar at gmail.com> escreveu:  
 
 
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

  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/grass-user/attachments/20220210/b6ca300a/attachment-0001.html>


More information about the grass-user mailing list