Using Obsidian for qualitative analysis — a starter environment

A while back, I built a vault to use Grounded Field Theory to conduct qualitative analysis of some 1900+ open-ended survey responses.

It worked really well, so I have open-sourced the environment and wrote it up at the post below. Hope it helps others!

Aside: this downloadable environment is an example of what I’m calling an “Integrated Thinking Environment.” Lately I’ve started to think of Obsidian as an operating system for these kinds of environments.


This is such an interesting application of Obsidian. I have been wondering if such a thing was could work in my own research. Thank you so much for making the files available and for the nice explanation on the blog post too.

1 Like

And the idea of an “integrated thinking environment” is intriguing too.

1 Like

Thank you @ryanjamurphy your effort! This is truly great, and I finally had the time to play around a little with your example project. I have a couple of questions, though. You mention that one could use the daily notes plugin to quickly traverse through data points. Would you mind explaining a little how this would work? I set up the hotkey and pointed the plugin to my data points folder for creating new notes, however, I don’t understand how to get the plugin to go from one file to the next one. Is the trick to create every data point as a fake daily note, such that the plugin thinks of it as daily notes? If yes, how would one handle the naming of the files?

Thank you! :slight_smile:

1 Like

So cool! Thanks @ryanjamurphy for sharing this! I haven’t fully gone through the system, but from my view so far, it reminds me of something I was trying to do as almost a simplified version of this when I first started to try to understand Obsidian. I was moving through heaps of ideas I have had for a project and trying to craft all the oddities and unique parts into lists and soon they morphed into commonalities. I felt like the most important results were actually from the realizations of all the various modes and levels of similarities rather than the similarities themselves. I am going to have to dig in further to what you have shared here but I greatly appreciate it as it has relit a flame that had weakened. Great work!

1 Like

I didn’t really explain this fully, sorry. The idea is to break up your data into pieces and to name them sequentially—literally 1, 2, 3, 4, […], 1000. I didn’t provide a way of doing this, though perhaps I should. On macOS it can be easily done with the system bulk file renaming options (e.g., select all files, then in the menu select File → Rename….

1 Like

Thank you, however this was not the issue. :sweat_smile: Maybe I did a bad job in terms of explaining what the problem is. I wondered how it is possible to “tell” the daily notes plugin that it should traverse the data pieces (1, 2…10…)? set a shortcut for both ‘Open next’ and ‘Open previous daily note’ and also pointed the daily notes plugin to the data points folder. Yet the keyboard shortcut did nothing, presumably because it was looking for note titles with the syntax YYYY-MM-dd. However… writing this response made me reconsider the problem and I figured that changing the date format syntax could do the trick. So I looked up the format reference and looked for a format which would allow for 1, 2, 3 etc. Turns out that Y works (“Year with any number of digits and sign”). So I changed the date syntax to “Y” and it now works perfectly together with keyboard shortcuts.

Oh, sorry, yes! I will edit the instructions to specify that the date format needs to be YYYY.

(We’re tricking the Daily Notes plugin, here. It simply thinks that we’re working on a note for year 1, year 2, etc. Heh.)

1 Like

If anyone comes across using R and is using Ryan’s method, I can save you a few minutes importing your vault. I wrote a library with a function to read a folder of markdown files and pull the codes/wikilinks out. It’s my first R project, so I might not have structured the data right - if there’s anything I can do to make it easier to import to other packages or standards, submit an issue.

1 Like

Thank you @ryanjamurphy I really like your work. I’m adapting it into my current research now. I have a question which is how do you deal with hierarchical themes? To put it another way, I have Themes >> Sub-Themes >> Codes, how should I demonstrate their levels?

In Nvivo I believe it’s quite easy to set this kind of code level.

1 Like

Sorry for the delayed response.

The trouble with that kind of question is that there are many answers. Off the top of my head, I’d consider linking themes to one another. In fact, this allows arbitrary nesting: themes a, b, and c could all point to theme 1, which could point to theme α, etc.

You could also get into metadata for this, giving data or themes different metadata and then using e.g., dataview to query it.

So, a lot of this is up to you. I don’t know if there’s a “best” way!

1 Like

I’d love to use this for my dissertation. Thanks for this Ryan. Hierarchical themes would be nice too. I’ll play around with it in a few weeks when I’m done with this semester but if you have examples of how to do hierarchical themes that would be great. A screenshot perhaps? I read your response but not entirely sure how that would work. I’m not very good at dataview and I’m not entirely sure what you mean by arbitrary nesting.

Have you ever heard of Second Brain PKM Insights with AI and Text Graph Visualization. I was thinking about using this software along with your approach.

I have not looked into Nodus at all, sorry.

The new Canvas tool may be very useful for this kind of hierarchical coding:

On the off-chance this is helpful to someone, here’s a python script to convert a CSV file into individual data files (one file per row)

import csv
import os

# Create the data subfolder if it doesn't already exist
if not os.path.exists('data'):

# Open the CSV file and read the rows
with open('input.csv', 'r') as csv_file:
  reader = csv.reader(csv_file)

  # Read the header row
  header = next(reader)

  for i, row in enumerate(reader):
    # Transpose the row and write it to a new file in the data subfolder
    filename = f"{i:04}.md"  # Use four-digit filename with leading zeros
    with open(os.path.join('data', filename), 'w') as output_file:
      output_file.write('\n'.join([f"{header[i]}: {row[i]}" for i in range(len(row))]))

1 Like

Nice! There’s a similar script available here: