定性コーディングのための分析メモ
Potato のメモは、アイテム、テキストの一節、描かれた図形に付けられ、返信を受け付けます。課題として提起されたメモは、誰かが課題を解決するまで未解決のままです。
Potato のメモは、アイテム、アイテム内のテキスト選択、または画像上に描かれた図形に付けられる、自由記述のノートです。メモを読めるユーザーは誰でもそのメモに返信でき、課題として提起されたメモは、作成者、担当者、または裁定者が課題を解決するまで未解決のままです。メモは、QDA モードの有無にかかわらず、どの Potato プロジェクトでも動作し、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 ブロックはリードアナリストを指名し、裁定者はプロジェクト内のすべてのメモを読めます。
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.visibility | private | visibility フィールドなしで API を通じて作成されたメモの公開範囲。private と shared 以外の値は、private にフォールバックします。 |
qda_mode.memos.show_sidebar_by_default | true | QDA モードの下で、アノテーターが閉じるまで、各アイテムで Notes パネルを開きます。 |
qda_mode.memos.enabled | true | 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 パネルは、現在のアイテムのメモを古い順に一覧し、各スレッドの返信は最初のノートの下に表示されます。メモを追加するには、次のようにします。
- アノテーションページの右端にある Notes をクリックします。
- メモを一節にアンカーするには、先にアイテム内のテキストを選択し、Attach to selected text にチェックを入れます。メモを描かれた図形にアンカーするには、画像のキャンバスで図形を選択し、Attach to the selected shape にチェックを入れます。
- コンポーザーにノートを入力します。
- ノートを課題として提起するには、Raise as an issue to resolve にチェックを入れます。任意で、課題を解決すべき人のユーザー名を Assign to に入力します。
- 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 イベントに登録します。このイベントは、課題に新しい担当者が付くたびに発火し、メモの ID、アイテムの ID、担当者、課題を割り当てたユーザー、ステータスを送ります。課題が非公開の場合があるため、ペイロードにはメモのテキストは含まれません。
管理ダッシュボードの課題
メモがオンのとき、管理ダッシュボードの Overview タブには、未解決の課題の数と解決済みの数を示す Open issues タイルが表示されます。管理 API は、非公開のものを含め、課題そのものを一覧します。
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 を指定すると、エクスポーターはメモと返信ごとに一行を追加します。
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 での作成時刻、スレッドのステータス、担当者、解決者とともに一覧します。
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 のチェックアウトから実行します。
python potato/flask_server.py start examples/advanced/memos-example/config.yaml -p 8000この例は、一つの感情の質問を持つ四つの短い商品レビューに対して、非公開のメモをオンにします。この例には span スキームがなく、引用レポートはこの例のメモをエクスポートできません。QDA モードの例には、コードブックに基づく span スキームがあります。エクスポートを試すには、examples/advanced/qda-mode-example/config.yaml を実行してください。
関連資料
- QDA モード。メモとともに QDA モードがオンにするコードブック、ケース、検索について
- 質的研究におけるコーダー間信頼性。メモをいつ非公開に保つかについて
- エクスポート形式。エクスポーターの完全なリファレンス
- 管理ダッシュボード。API キーと Overview タブについて
- ウェブフック。
memo.issue_assignedイベントの配信について
実装の詳細については、ソースドキュメントを参照してください。
参考文献
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