跳轉到內容

質性編碼中的分析備忘錄

Potato 的備忘錄可附在條目、一段文本或一個繪製的形狀上,並可接受回覆。作為議題提出的備忘錄會一直保持未解決狀態,直到有人解決該議題。

Potato 中的備忘錄是附在條目、條目內的一段文本選區或影像上繪製的形狀上的自由文本筆記。任何能讀到某條備忘錄的使用者都可以回覆這條備忘錄;作為議題(issue)提出的備忘錄會一直處於未解決狀態,直到作者、被指派人或裁定者解決該議題。備忘錄適用於任何 Potato 項目,無論是否啟用 QDA 模式,Potato 都把備忘錄儲存在項目資料庫中,而不是標註檔案裡。備忘錄在 Potato 2.6.0 中加入,回覆和議題在 2.12.0 中加入。

分析備忘錄是研究者在編碼過程中針對資料和程式碼寫下的筆記,例如某個程式碼為何適合某段文字,或碼本哪裡需要一條新規則。撰寫備忘錄最常被描述為紮根理論的一部分,Birks、Chapman 和 Francis(2008) 則建議在各種質性方法中都撰寫備忘錄。按照這幾位作者的說法,備忘錄幫助分析者從原始資料走向解釋這些資料的抽象概念。在編碼團隊中,備忘錄還記錄了程式碼背後的決定,下文介紹的匯出會把這些筆記變成一份審計軌跡。

每條備忘錄記錄以下內容:

  • 錨點。 備忘錄附在整個條目上、條目文本的一個字元範圍上(顯示為 quote 徽標),或一個繪製的形狀上(顯示為該形狀的標籤和類型,例如 car box)。
  • 可見性。 備忘錄為 private(預設)或 shared。
  • 討論串。 回覆排在第一條筆記之下,並沿用第一條筆記的可見性。
  • 議題狀態。 議題為 open 或 resolved,可以有一名被指派人,並記錄由誰在何時解決了該議題。
  • 儲存。 點選 Add note 後備忘錄即被儲存,存放在 <task_dir>/project.sqlite 的 memos 和 memo_threads 表中。

啟用備忘錄

標準項目中備忘錄預設關閉,在 QDA 模式和單人模式下預設開啟。項目通過 annotation_ui 程式碼塊啟用備忘錄。下面的配置為一個團隊設定了用 span 方案編碼訪談摘錄的任務,並使用私有備忘錄。adjudication 程式碼塊指定了一名首席分析者,裁定者可以讀到項目中的每一條備忘錄:

yaml
annotation_task_name: Clinic access interviews
task_dir: .
output_annotation_dir: annotation_output/
data_files:
- data/excerpts.json
item_properties:
  id_key: id
  text_key: text
 
annotation_ui:
  memos: true
  visibility: private
 
adjudication:
  enabled: true
  adjudicator_users: [lead_analyst]
 
annotation_schemes:
- annotation_type: span
  name: codes
  description: Highlight a passage and apply a code
  labels: [transport barriers, cost concerns, provider trust]

span 方案對匯出很重要,因為引文報告需要一個 span 方案(見匯出備忘錄)。有四個鍵控制備忘錄:

選項預設值說明
annotation_ui.memos關閉;當 qda_mode.enabled 或 solo_mode.enabled 為 true 時開啟顯示 Notes 面板並啟用 /api/memos 端點。顯式的 true 或 false 會覆蓋 QDA 模式和單人模式的預設值。
annotation_ui.visibilityprivate通過 API 建立、未帶 visibility 欄位的備忘錄所用的可見性。private 或 shared 以外的任何值都會回退為 private。
qda_mode.memos.show_sidebar_by_defaulttrue在 QDA 模式下,在每個條目上開啟 Notes 面板,直到標註者關閉該面板。
qda_mode.memos.enabledtrue在 QDA 模式下,設為 false 會讓 Notes 面板一開始保持關閉。備忘錄仍然可用;關閉備忘錄的鍵是 annotation_ui.memos: false。

在 QDA 模式之外,Notes 面板一開始是關閉的,標註者通過頁面右邊緣的 Notes 按鈕打開面板。關閉面板後,在該瀏覽器標籤頁會話的剩餘時間裡,後續條目上的面板也保持關閉。備忘錄關閉時,Potato 不渲染 Notes 按鈕,/api/memos 端點返回 503。在每個項目中,編輯框的可見性選單都從 Private 開始,annotation_ui.visibility 不會改變這個選單。希望使用共享備忘錄的團隊,需要請編碼者為每條新備忘錄選擇 Shared。

Potato 把每條備忘錄歸檔在項目的 annotation_task_name 之下。在配置中給任務改名後,舊名稱下寫的備忘錄就會被隱藏。這些記錄仍留在 project.sqlite 中,恢復舊名稱後備忘錄會重新出現。

在 Notes 面板中撰寫備忘錄

Notes 面板按從舊到新的順序列出當前條目上的備忘錄,每個討論串的回覆排在第一條筆記之下。新增備忘錄的步驟:

  1. 點選標註頁面右邊緣的 Notes。
  2. 要把備忘錄錨定到一段文字,先在條目中選中文本,再勾選 Attach to selected text。要把備忘錄錨定到一個繪製的形狀,先在影像畫布上選中該形狀,再勾選 Attach to the selected shape。
  3. 在編輯框中輸入筆記。
  4. 要把筆記作為議題提出,勾選 Raise as an issue to resolve。也可以在 Assign to 下輸入應當解決該議題的人的使用者名稱。
  5. 在 Visibility 下選擇 Private 或 Shared,然後點選 Add note。

每條備忘錄只顯示當前使用者可以使用的按鈕。Reply 出現在每個討論串上,Resolve 或 Reopen 以及 Assign 出現在該使用者有權更改的議題上,Edit 和 Delete 出現在該使用者自己的備忘錄上。裁定者還會在其他使用者的備忘錄上看到 Delete。編輯第一條筆記時,除了文本,還可以更改筆記的可見性。

文本錨點記錄選區在條目顯示文本中的起止字元偏移量,結束偏移量不包含在內。只有在條目的主文本顯示區域內的選區才會被計入。形狀錨點記錄形狀的方案、類型、標籤和歸一化座標,因為繪製的形狀沒有儲存的 ID。點選備忘錄上的形狀徽標,會通過匹配儲存的座標重新選中該形狀。如果形狀此後被移動或刪除,面板會提示該形狀已不在影像上原來繪製的位置。

誰能讀到備忘錄

私有備忘錄只有作者和裁定者能讀到。共享備忘錄項目中的每個使用者都能讀到。議題的被指派人即使在議題為私有時,也能讀取和回覆該議題的討論串。備忘錄的其餘規則如下:

  • 只有作者可以編輯備忘錄的文本或可見性。
  • 作者或裁定者可以刪除備忘錄。刪除討論串的第一條筆記會同時刪除其回覆。
  • 任何能讀到討論串的人都可以回覆。回覆沿用第一條筆記的可見性,之後對第一條筆記可見性的更改也會作用於回覆。
  • 對於使用者無法讀取的備忘錄,每個操作都返回 404。Potato 對不存在的備忘錄給出同樣的響應。

對備忘錄而言,裁定者是指在 adjudication.enabled 為 true 時列在 adjudication.adjudicator_users 中的使用者名稱。Potato 在處理備忘錄時只檢查這份名單。持有 RBAC admin 角色但不在名單上的使用者,讀到的備忘錄與普通標註者相同。

私有備忘錄只在標註介面內是私有的。任何執行引文報告匯出或開啟 project.sqlite 的人都能讀到每一條備忘錄,包括私有備忘錄。請在編碼開始前告訴編碼者這項匯出。

共享備忘錄讓編碼者在編碼時能讀到彼此的推理。當兩名編碼者為編碼者間信度檢驗獨立編碼同一批摘錄時,共享備忘錄可能錨定第二名編碼者的判斷,並因與碼本無關的原因抬高一致性。在信度輪次中請保持備忘錄私有。該輪結束後,編碼者可以用 Edit 開啟每條私有備忘錄,並將其切換為 Shared,供協調會議使用。

回覆與議題

每條備忘錄都會開啟一個討論串。回覆沒有獨立於第一條筆記的可見性或狀態。勾選 Raise as an issue to resolve 會讓第一條筆記的狀態變為 open。議題適合那些需要在繼續編碼前得到回答的問題,例如碼本沒有界定清楚的程式碼邊界。議題的許可權如下:

操作誰可以執行該操作
回覆任何能讀到該討論串的人
解決或重新開啟議題議題作者、被指派人或裁定者
指派議題或清除被指派人議題作者或裁定者

解決議題會記錄由誰在何時解決,重新開啟議題會清空這兩個欄位。清除指派會撤銷被指派人對私有議題的訪問許可權。當有未解決的議題指派給某位標註者時,Notes 按鈕會顯示數量,例如 Notes · 2 assigned to you,面板也會把這些議題列在頂部。位於該標註者自己佇列中的條目上的議題會帶有 Go to item 按鈕,不在佇列中的條目上的議題則標為不在佇列中。設定 jumping_to_id_disabled: true 會移除 Go to item 按鈕。

要把指派資訊傳送到聊天頻道或事務跟蹤系統,請為 memo.issue_assigned 事件訂閱一個 webhook。每當議題有了新的被指派人,該事件就會觸發,併發送備忘錄 ID、條目 ID、被指派人、執行指派的使用者和狀態。由於議題可能是私有的,載荷中不包含備忘錄的文本。

管理儀表板中的議題

備忘錄開啟時,管理儀表板的 Overview 標籤頁會顯示一個 Open issues 卡片,列出未解決議題的數量和已解決的數量。管理 API 會列出議題本身,包括私有議題:

bash
curl -H "X-API-Key: $POTATO_ADMIN_KEY" \
  "http://localhost:8000/admin/api/memo_issues?status=open"

響應中每個議題對應一項,按從新到舊排列,包含備忘錄的文本、作者、條目 ID、錨點、被指派人、狀態和解決人。使用 ?status=resolved 獲取已解決的議題,省略該參數則同時返回兩類。該端點只列出議題。普通備忘錄要通過匯出或裁定者賬戶才能到達項目負責人手中。

匯出備忘錄

quotation_report 匯出器為每個已編碼的跨度寫一行 CSV。加上 include_memos=true 後,匯出器會為每條備忘錄和每條回覆各加一行:

bash
python -m potato.export -c config.yaml -f quotation_report \
  --option include_memos=true -o ./export/

該命令會寫出 ./export/quotations.csv。備忘錄行與跨度行使用相同的九列:

列備忘錄行中的值
schema(memo)、(memo reply)、(issue: open) 或 (issue: resolved)
code討論串的可見性,private 或 shared
text備忘錄的文本
start, end文本錨點的字元偏移量,其他情況為空
field文本錨點為 text,其他情況為空
instance_id備忘錄所在的條目
source_doc條目文本的前 200 個字元
coder備忘錄的作者

只有當配置中至少有一個 span 方案時,該匯出器才會執行。只用 radio 或 multiselect 題目編碼的研究會得到錯誤 No span annotation schema found in config。備忘錄行也沒有時間戳和被指派人,錨定在形狀上的備忘錄匯出時偏移量為空。

如需帶日期的審計軌跡,請直接查詢兩張備忘錄表。下面的 sqlite3 命令列出項目中的每條備忘錄,包括 UTC 建立時間、討論串狀態、被指派人和解決人:

bash
sqlite3 -header -csv project.sqlite "
  SELECT m.instance_id, m.created_by, datetime(m.created_at, 'unixepoch') AS created,
         m.visibility, t.parent_id, t.status, t.assignee, t.resolved_by, m.body
  FROM memos m LEFT JOIN memo_threads t ON t.memo_id = m.id
  WHERE m.project = 'Clinic access interviews'
  ORDER BY m.created_at" > memos.csv

非空的 parent_id 表示這是一條回覆,並指明討論串的第一條筆記。Potato 以 Unix 秒儲存時間,resolved_at 和 updated_at 的轉換方式與 created_at 相同。

備忘錄不會進入 REFI-QDA .qdpx 匯出。當配置設定了 annotation_ui.memos: true 時,.qdpx 匯出器會警告備忘錄被略去。在未設定該鍵的 QDA 模式或單人模式下,匯出會略去備忘錄且不發出警告。項目遷移到其他 QDA 程式時,請用引文報告單獨匯出備忘錄。

potato snapshot create 構建的歸檔包含 project.sqlite,potato deploy pull 生成的歸檔同樣包含該檔案。因此這兩種歸檔都儲存了每一條備忘錄,包括私有備忘錄。快照的內容雜湊覆蓋配置、研究的檔案和標註。雜湊不包括資料庫,新增備忘錄不會改變雜湊。參見項目快照。

備忘錄 API

Notes 面板使用 /api/memos 下的 REST API,通過標註者的登入會話認證。指令碼也可以呼叫同樣的端點:

請求用途
GET /api/memos?instance_id=<id>某個條目上該使用者可讀的備忘錄和回覆,每項帶有 can_edit、can_delete、can_resolve 和 can_assign
POST /api/memos由 instance_id、body、visibility 和 anchor 建立新備忘錄;議題另加 issue: true 和可選的 assignee
POST /api/memos/<id>/reply帶 body 的回覆
PATCH /api/memos/<id>更改 body、visibility、status(open 或 resolved)或 assignee(留空即清除)
DELETE /api/memos/<id>刪除備忘錄;若該備忘錄是第一條筆記,則連同回覆一起刪除
GET /api/memos/issues?status=open&assignee=me整個項目中該使用者可讀的議題

文本錨點形如 {"start": 48, "end": 98, "field": "text"},形狀錨點形如 {"shape": {"schema": ..., "type": ..., "label": ..., "coordinates": ...}}。對不在項目中的條目 ID 傳送 POST 會返回 400。

示例

Potato 的倉庫附帶一個備忘錄示例。在 Potato 程式碼檢出目錄中執行該示例:

bash
python potato/flask_server.py start examples/advanced/memos-example/config.yaml -p 8000

該示例在四條簡短的產品評論上啟用私有備忘錄,並配有一道情感題目。該示例沒有 span 方案,引文報告無法匯出該示例的備忘錄。QDA 模式示例帶有以碼本為支撐的 span 方案。要試用匯出,請執行 examples/advanced/qda-mode-example/config.yaml。

延伸閱讀

有關實現細節,請參見源文件。

參考文獻

Birks, M., Chapman, Y., and Francis, K. (2008). Memoing in qualitative research: Probing data and processes. Journal of Research in Nursing, 13(1), 68–75. doi:10.1177/1744987107081254