There's an additional wrinkle here that I didn't notice at first. If each of your levels has the same number of things, then you can build a dictionary and then use it to supply the table's columns to PrettyTable:
from prettytable import PrettyTable
# Create an empty dictionary.
levels = {}
with open('data.txt') as f:
    for line in f:
        # Remove trailing \n and split into the parts we want.
        thing, level = line.rstrip('\n').split(' - ')
        
        # If this is is a new level, set it to a list containing its thing.
        if level not in levels:
            levels[level] = [thing]
        # Otherwise, add the new thing to the level's list.
        else:
            levels[level].append(thing)
# Create the table, and add each level as a column
table = PrettyTable()
for level, things in levels.items():
    table.add_column(level, things)
print(table)
For the example data you showed, this prints:
+---------+----------+----------+
| level 1 | level 3  | level 2  |
+---------+----------+----------+
| thing_1 | thing_17 | thing_22 |
+---------+----------+----------+
The Complication
I probably wouldn't have posted an answer (believing it was covered sufficiently in this answer), except that I realized there's an unintuitive hurdle here. If your levels contain different numbers of things each, you get an error like this:
Exception: Column length 2 does not match number of rows 1!
Because none of the solutions readily available have an obvious, "automatic" solution to this, here is a simple way to do it. Build the dictionary as before, then:
# Find the length of the longest list of things.
longest = max(len(things) for things in levels.values())
table = PrettyTable()
for level, things in levels.items():
    # Pad out the list if it's shorter than the longest.
    things += ['-'] * (longest - len(things))
    table.add_column(level, things)
print(table)
This will print something like this:
+---------+----------+----------+
| level 1 | level 3  | level 2  |
+---------+----------+----------+
| thing_1 | thing_17 | thing_22 |
|    -    |    -     | thing_5  |
+---------+----------+----------+
Extra
If all of that made sense and you'd like to know about a way part of it can be streamlined a little, take a look at Python's defaultdict. It can take care of the "check if this key already exists" process, providing a default (in this case a new list) if nothing's already there.
from collections import defaultdict
levels = defaultdict(list)
with open('data.txt') as f:
    for line in f:
        # Remove trailing \n and split into the parts we want.
        thing, level = line.rstrip('\n').split(' - ')
        
        # Automatically handles adding a new key if needed:
        levels[level].append(thing)