frequency tool

1648
5
01-06-2012 11:12 AM
SandraMargriter
New Contributor II
Does anyone know why the case_item field was eliminated from the frequency tool in ArcGIS Desktop? In ArcInfo Workstation the option to add a case_item made it very easy to join the frequency table to the feature table. This question was initially asked in 2007 (http://forums.esri.com/thread.asp?c=93&f=1729&t=233587), but did not get a response.
0 Kudos
5 Replies
RichardFairhurst
MVP Honored Contributor
Does anyone know why the case_item field was eliminated from the frequency tool in ArcGIS Desktop? In ArcInfo Workstation the option to add a case_item made it very easy to join the frequency table to the feature table. This question was initially asked in 2007 (http://forums.esri.com/thread.asp?c=93&f=1729&t=233587), but did not get a response.


That does seem like a useful behavior.  Since not all source feature classes can have their schemas altered (SDE won't allow it without priveleges) the option should be added to the Desktop tool but be greyed out if the user lacks rights to alter the source schema.  I also suppose that locks on the source by other users are hard to detect and would cause that option to fail, so the tools was simplified to allow it to work without much chance of generating errors.  The Make Query Table tool is the only option for doing this kind of join in Desktop, but it has to be in the same geodatabase to work and cannot be edited, so if you can use that tool it has to be exported to create the joinable bridge table.  That is not as elegant of an approach.  Concatenating the fields together in a new field that is in both the source and output is the only other option to create a join.

You should vote for this idea and similar ideas on the ideas website.
0 Kudos
ChrisSnyder
Regular Contributor III
Use the SummaryStatistics tool: http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00080000001z000000.htm

It does everything that Frequecy does and more...
0 Kudos
RichardFairhurst
MVP Honored Contributor
Use the SummaryStatistics tool: http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00080000001z000000.htm

It does everything that Frequecy does and more...


I agree that it does everything that Frequency does and more, but it still does not add a case item field to the source if the output has more than one case field.  That functionality would be a good enhancement so that Relationship Classes can be established for correlating many fields to a single join field.  So I still recommend voting for the idea I mentioned to request that enhancement.
0 Kudos
ChrisSnyder
Regular Contributor III
Right I get it... as Amanda (circa 2007) states, there is no way to do this except to create a concatenated field in the input and output tables. Not that much overhead though really.

Another option I use a lot is to populate a Python dictionary such as:

relateDictionary = {(1,2) = "cat", (2,2) = "dog"}

where 1,2 and 2,2 are unique combinations of the relate keys, but that requires some programming using a search and update cursor...
0 Kudos
KimOllivier
Regular Contributor II
I miss this function too, especially when attempting to port  AML code to  Python tools.

Here is a python script  that  I called FrequencyWithCase to add back the functionality.
It was not too hard, I can add the case ID as the records are read in a single pass updateCursor.
# FrequencyWithCase.py
# do it properly ESRI
# 19 May 2010
# add a case item to the source table
# like Workstation

import arcgisscripting,sys,os

try :
    table = sys.argv[1]
    strFields = sys.argv[2]
except :
    table = "e:/data/nzpost/paf2010/geopaf.gdb/pafpost"
    strFields = "postcode;postcode_1"

gp = arcgisscripting.create(9.3)
casefld = "case"
ws = os.path.dirname(table)
tabname = os.path.basename(table)

gp.Workspace = ws

if len(gp.Listfields(table,casefld)) == 0 :
    result = gp.AddField(table,casefld,"LONG")
    print result.GetOutput(0)
else :
    # name = gp.AddField(table,"case1","LONG")
    print casefld,"Exists"
if gp.ListFields(table,casefld) == None :
    raise Exception,"no case field"
seqfld = 'sequence'
if len(gp.Listfields(table,seqfld)) == 0 :
    result = gp.AddField(table,seqfld,"LONG")
    print result.GetOutput(0)
else :
    # name = gp.AddField(table,"case1","LONG")
    print seqfld,"Exists"
if gp.ListFields(table,seqfld) == None :
    raise Exception,"no sequence field"
# make a dictionary with a combo key
# populate the source table as we go
# export the dictionary at the end

# make a tuple of all fields
# check if its in dictionary
# if it is increment counter
# otherwise add new entry
# retrieve number
# put number into index or back on table

# 
dFreq = {}
lstFields = strFields.split(";")
print lstFields
cur = gp.UpdateCursor(table)
row = cur.next()
n = 0
ccase = 0
while row:
    combo = []
    for f in lstFields :
        combo.append( row.GetValue(f) )
    combo = tuple(combo)
    if dFreq.has_key(combo) :
        thiscase,freq = dFreq[combo]
        dFreq[combo] = (thiscase,freq+1)
        row.case = thiscase
        row.sequence = freq+1
    else :
        ccase+=1
        dFreq[combo] = (ccase,1)
        row.case = ccase
        row.sequence = 1
    cur.UpdateRow(row)
##    if n > 1000 :
##        break
    n+=1
    row = cur.next()
del cur,row
print

print "case freq"
keytab = dFreq.values()
keytab.sort()
##for x in keytab:
##    print "%4d %4d" % x
print len(dFreq),"cases"

# write out frequency table with case item

fTab = tabname+"Freq"
if gp.Exists(fTab) :
    gp.Delete(fTab)
gp.CreateTable(ws,fTab)
gp.AddField(fTab,casefld,"LONG")
gp.AddField(fTab,"Frequency","LONG")
dscTable = gp.Describe(table)
dType = {"String":"TEXT","Integer":"LONG"}
for f in lstFields:
    fType = dType[gp.ListFields(table,f)[0].type]
    gp.AddField(fTab,f,fType) # may not be a "long" in general case
    print f,"added to",fTab    
cur = gp.InsertCursor(fTab)
for k in dFreq.keys():
    ## print dFreq[0],dFreq[1],dFreq
    row = cur.NewRow()
    row.case = dFreq[0]
    row.Frequency = dFreq[1]
    n = 0
    for i in k:
        ##print i,n,lstFields
        fld = lstFields
        row.SetValue(fld, i)
        n+=1
    cur.InsertRow(row)
del cur,row
print "Done"
0 Kudos