{ "cells": [ { "cell_type": "code", "execution_count": 21, "id": "a2480175-ba31-4e02-bb87-16697c17c075", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "from scipy import stats, sparse\n", "import bottleneck\n", "\n", "def run_egad(go, nw, **kwargs):\n", " \"\"\"EGAD running function\n", " \n", " Wrapper to lower level functions for EGAD\n", "\n", " EGAD measures modularity of gene lists in co-expression networks. \n", "\n", " This was translated from the MATLAB version, which does tiled Cross Validation\n", " \n", " The useful kwargs are:\n", " int - nFold : Number of CV folds to do, default is 3, \n", " int - {min,max}_count : limits for number of terms in each gene list, these are exclusive values\n", "\n", "\n", " Arguments:\n", " go {pd.DataFrame} -- dataframe of genes x terms of values [0,1], where 1 is included in gene lists\n", " nw {pd.DataFrame} -- dataframe of co-expression network, genes x genes\n", " **kwargs \n", " \n", " Returns:\n", " pd.DataFrame -- dataframe of terms x metrics where the metrics are \n", " ['AUC', 'AVG_NODE_DEGREE', 'DEGREE_NULL_AUC', 'P_Value']\n", " \"\"\"\n", " assert nw.shape[0] == nw.shape[1] , 'Network is not square'\n", " #print(nw.index)\n", " #nw.columns = nw.columns.astype(int)\n", " #print(nw.columns.astype(int))\n", " assert np.all(nw.index == nw.columns) , 'Network index and columns are not in the same order'\n", "\n", " #nw_mask = nw.isna().sum(axis=1) != nw.shape[1]\n", " #nw = nw.loc[nw_mask, nw_mask].astype('float')\n", " #np.fill_diagonal(nw.values, 1)\n", " return _runNV(go, nw, **kwargs)\n", "\n", "def _runNV(go, nw, nFold=3, min_count=20, max_count=1000):\n", "\n", " #Make sure genes are same in go and nw\n", " #go.index = go.index.map(str) \n", " #nw.index = nw.index.map(str)\n", " #nw.index = nw.index.str.replace('_', '')\n", " #go.index = go.index.str.replace('_', '')\n", " #print (nw)\n", " genes_intersect = go.index.intersection(nw.index)\n", "\n", "\n", " #print (genes_intersect)\n", " go = go.loc[genes_intersect, :]\n", " nw = nw.loc[genes_intersect, genes_intersect]\n", " #print (go)\n", " print (nw.shape)\n", " print (go.shape)\n", " sparsity = 1.0 - np.count_nonzero(go) / go.size\n", " print (sparsity)\n", " sparsity = 1.0 - np.count_nonzero(nw) / nw.size\n", " print (sparsity)\n", " #print(nw\n", " #print(go\n", " nw_mask = nw.isna().sum(axis=1) != nw.shape[1]\n", " nw = nw.loc[nw_mask, nw_mask].astype('float')\n", " np.fill_diagonal(nw.values, 1)\n", " #Make sure there aren't duplicates\n", " duplicates = nw.index.duplicated(keep='first')\n", " nw = nw.loc[~duplicates, ~duplicates]\n", "\n", " go = go.loc[:, (go.sum(axis=0) > min_count) & (go.sum(axis=0) < max_count)]\n", " go = go.loc[~go.index.duplicated(keep='first'), :]\n", " #print(go)\n", "\n", " roc = _new_egad(go.values, nw.values, nFold)\n", "\n", " col_names = ['AUC', 'AVG_NODE_DEGREE', 'DEGREE_NULL_AUC', 'P_Value']\n", " #Put output in dataframe\n", " return pd.DataFrame(dict(zip(col_names, roc)), index=go.columns)\n", "\n", "def _new_egad(go, nw, nFold):\n", "\n", " #Build Cross validated Positive\n", " x, y = np.where(go)\n", " #print(x, y)\n", " cvgo = {}\n", " for i in np.arange(nFold):\n", " a = x[i::nFold]\n", " #print(a)\n", " b = y[i::nFold]\n", " dat = np.ones_like(a)\n", " mask = sparse.coo_matrix((dat, (a, b)), shape=go.shape)\n", " cvgo[i] = go - mask.toarray()\n", "\n", " CVgo = np.concatenate(list(cvgo.values()), axis=1)\n", " #print(CVgo)\n", "\n", " sumin = np.matmul(nw.T, CVgo)\n", "\n", " degree = np.sum(nw, axis=0)\n", " #print(degree)\n", " #print(degree[:, None])\n", "\n", " predicts = sumin / degree[:, None]\n", " #print(predicts)\n", "\n", " np.place(predicts, CVgo > 0, np.nan)\n", "\n", " #print(predicts)\n", "\n", " #Calculate ranks of positives\n", " rank_abs = lambda x: stats.rankdata(np.abs(x))\n", " predicts2 = np.apply_along_axis(rank_abs, 0, predicts)\n", " #print(predicts2)\n", "\n", " #Masking Nans that were ranked (how tiedrank works in matlab)\n", " predicts2[np.isnan(predicts)] = np.nan\n", " #print(predicts2)\n", "\n", " filtering = np.tile(go, nFold)\n", " #print(filtering)\n", "\n", " #negatives :filtering == 0\n", " #Sets Ranks of negatives to 0\n", " np.place(predicts2, filtering == 0, 0)\n", "\n", " #Sum of ranks for each prediction\n", " p = bottleneck.nansum(predicts2, axis=0)\n", " n_p = np.sum(filtering, axis=0) - np.sum(CVgo, axis=0)\n", "\n", " #Number of negatives\n", " #Number of GO terms - number of postiive\n", " n_n = filtering.shape[0] - np.sum(filtering, axis=0)\n", "\n", " roc = (p / n_p - (n_p + 1) / 2) / n_n\n", " U = roc * n_p * n_n\n", " Z = (np.abs(U - (n_p * n_n / 2))) / np.sqrt(n_p * n_n *\n", " (n_p + n_n + 1) / 12)\n", " roc = roc.reshape(nFold, go.shape[1])\n", " Z = Z.reshape(nFold, go.shape[1])\n", " #Stouffer Z method\n", " Z = bottleneck.nansum(Z, axis=0) / np.sqrt(nFold)\n", " #Calc ROC of Neighbor Voting\n", " roc = bottleneck.nanmean(roc, axis=0)\n", " P = stats.norm.sf(Z)\n", "\n", " #Average degree for nodes in each go term\n", " avg_degree = degree.dot(go) / np.sum(go, axis=0)\n", "\n", " #Calc null auc for degree\n", " ranks = np.tile(stats.rankdata(degree), (go.shape[1], 1)).T\n", "\n", " np.place(ranks, go == 0, 0)\n", "\n", " n_p = bottleneck.nansum(go, axis=0)\n", " nn = go.shape[0] - n_p\n", " p = bottleneck.nansum(ranks, axis=0)\n", "\n", " roc_null = (p / n_p - ((n_p + 1) / 2)) / nn\n", " #print(roc)\n", " return roc, avg_degree, roc_null, P" ] }, { "cell_type": "code", "execution_count": 2, "id": "390162db-e8b8-4a30-821e-d5ef1ece8965", "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv('/sonas-hs/gillis/hpc/data/lohia/hi_c_data_processing/software/CoCoCoNet/gene2go/drosophila_gene2go.csv', delim_whitespace=True)\n", "\n", "df['val'] = 1\n", "\n", "go_table = pd.pivot_table(df, index=['NetworkIDs'], values=['val'],columns=['GO_term'])\n", "\n", "go_table = go_table.fillna(0)\n", "\n", "from hicmatrix import HiCMatrix as hm\n", "from hicmatrix.lib import MatrixFileHandler\n", "exp_file_path = \"/grid/gillis/data/lohia/hi_c_data_processing/genomes_jlee/drosophila_dist.h5\" \n", "exp_file = hm.hiCMatrix(exp_file_path)\n", "\n", "exp_genes_all = [x[3].decode() for x in exp_file.cut_intervals]\n", "exp_matrix = exp_file.matrix.toarray()\n", "np.fill_diagonal(exp_matrix , 1)\n", "df_exp = pd.DataFrame(exp_matrix , index=exp_genes_all , columns = exp_genes_all )\n", "\n", "\n", "df_2d = run_egad(go_table, df_exp)\n", "\n", "df_2d.to_csv('./del.csv', sep='\\t')" ] }, { "cell_type": "code", "execution_count": 27, "id": "02fd8bda-1c3b-46a0-8d17-6caa24639db7", "metadata": {}, "outputs": [], "source": [ "from hicmatrix import HiCMatrix as hm\n", "from hicmatrix.lib import MatrixFileHandler\n", "exp_file_path = \"/grid/gillis/data/lohia/hi_c_data_processing/genomes_jlee/drosophila_dist.h5\" \n", "exp_file = hm.hiCMatrix(exp_file_path)" ] }, { "cell_type": "code", "execution_count": 31, "id": "c12cf51c-cdcc-4209-b6b2-1066a3285ce5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([7.23276279e+10, 7.16760457e+10, 7.03841510e+10, ...,\n", " 6.80401200e+07, 7.14493540e+07, 7.14627610e+07])" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exp_file.matrix.toarray().sum(axis=0)" ] }, { "cell_type": "code", "execution_count": 32, "id": "68d6e89d-6518-468c-845b-ccf2cef6bb3d", "metadata": {}, "outputs": [], "source": [ "exp_genes_all = [x[3].decode() for x in exp_file.cut_intervals]" ] }, { "cell_type": "code", "execution_count": 33, "id": "1f6b90d5-f0c1-497c-a898-1956274b16db", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
genesdegree
0FBgn02674317.232763e+10
1FBgn00858047.167605e+10
2FBgn00399877.038415e+10
3FBgn02677986.898037e+10
4FBgn02677976.689135e+10
.........
14871FBgn02508196.668846e+07
14872FBgn00399246.782980e+07
14873FBgn02631126.804012e+07
14874FBgn00271017.144935e+07
14875FBgn00536537.146276e+07
\n", "

14876 rows × 2 columns

\n", "
" ], "text/plain": [ " genes degree\n", "0 FBgn0267431 7.232763e+10\n", "1 FBgn0085804 7.167605e+10\n", "2 FBgn0039987 7.038415e+10\n", "3 FBgn0267798 6.898037e+10\n", "4 FBgn0267797 6.689135e+10\n", "... ... ...\n", "14871 FBgn0250819 6.668846e+07\n", "14872 FBgn0039924 6.782980e+07\n", "14873 FBgn0263112 6.804012e+07\n", "14874 FBgn0027101 7.144935e+07\n", "14875 FBgn0053653 7.146276e+07\n", "\n", "[14876 rows x 2 columns]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data_tuples = list(zip([x[3].decode() for x in exp_file.cut_intervals],exp_file.matrix.toarray().sum(axis=0)))\n", "pd.DataFrame(data_tuples, columns=['genes','degree'])" ] }, { "cell_type": "code", "execution_count": 23, "id": "7c1e6c69-e1bd-457c-9375-dd5752877d8a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAA420lEQVR4nO3de5xM9f/A8ddn12AX2c3qtkhXtRKyvyhddPl+6aJUSrp9aVkSfV1SSEmEXL6RXEsplQht5BaJ5BbadUtKErtUWEvsYi+f3x9rttm5ntmdmTOX9/Px6JGdc2bmfXZ23udzPufzeX+U1hohhBChL8rsAIQQQviGJHQhhAgTktCFECJMSEIXQogwIQldCCHCRAWz3jghIUHXrVvXrLcXwud27doFQL169UyORISzzZs3H9Za13S2zbSEXrduXTZt2mTW2wvhcy1atABg5cqVpsYhwptS6ndX26TLRQghwoRpLXQhws3AgQPNDkFEOEnoQvjInXfeaXYIIsJJl4sQPpKRkUFGRobZYYgIJi10IXykZ8+egNwUFebx2EJXSr2nlPpLKbXdxXallHpLKbVbKbVVKXWd78MUQgjhiZEul+lAKzfb7wKuOPtfKjCp/GEJIYTwlseErrX+Fsh2s8v9wIe62HogTil1oa8CFEKIcJGfn8+IESPYuHGjX17fFzdFE4H9Nj9nnn3MgVIqVSm1SSm16dChQz54ayGECA3p6ek0bdqU/v37M3fuXL+8hy9uiionjzldNUNrPRWYCpCcnCwra4iwMmzYMLNDEEHo1KlTDBkyhDfeeIOEhATmzJnDQw895Jf38kVCzwRq2/xcCzjgg9cVIqTceOONZocggsyaNWtISUlh165ddOzYkTFjxhAfH++39/NFl8t84Kmzo12aAce01gd98LpChJS1a9eydu1as8MQQeDvv/+mR48e3HzzzZw6dYqlS5fy3nvv+TWZg4EWulJqJtACSFBKZQKDAAuA1noysAi4G9gN5AId/RWsEMFswIABgIxDj3RLly4lNTWV/fv306NHD15//XWqVq0akPf2mNC11u09bNfAsz6LSAghQlB2dja9e/fmgw8+4KqrrmL16tU0b948oDHI1H8hhCinuXPnkpSUxEcffcRLL71Eenp6wJM5yNR/IYQos4MHD9K9e3fmzZvHddddx5IlS2jUqJFp8UgLXQgh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qlTJ7NDKLJhX3vF3i9ZVV5CrSVFl6eu2v7kczL/vUCQJXZTJwYMH6datG2lpaTRp0oSvvvqKhg0bmh1WWPNVRUxP72H/eq6GWlqvDLyZMOWxfLEoF0nowitaa95//3169+7N6dOnGTlyJL169aJCBflTCgQzWrSergycbbuuTnXW/Jrt8Fq249CF78m3UBj222+/kZqayvLly7nlllt45513uPLKK80OS/iZkSsDZ9t8UW1ReMdQcS5/kOJcoaOwsJC3336bAQMGEB0dzciRI0lNTQ2KYlrBZNasWQC0a9fO5EhEOCt3cS4RuX788UdSUlJYv349d911F1OmTKF2bblsdkYSuTCbNLGEU2fOnGHIkCE0btyYX375hY8++oiFCxdKMndj//797N+/3/OOQviJtNCFg02bNpGSksLWrVt59NFHGTduHOedd57ZYQW9J598EoCVK1eaG4iIWNJCFyXy8vJ44YUXaNq0KYcPH+aLL75g5syZksyFCBHSQhcArFq1ik6dOrF79246d+7MyJEjiYuLMzssIYQXJKFHuOPHj/Piiy8yefJkLr30Ur7++mtuv91YkSkhzCILYzgnCT2CLVy4kK5du3LgwAF69+7Na6+9RpUqVcwOSwi3ZGEM1yShR6DDhw/Ts2dPPv74Y+rXr8+cOXNo2rSp2WGFvD59+pgdQkSQhTFck4QeQbTWzJo1ix49enDs2DEGDRrEgAEDqFixotmhhYXWrVubHUJEkIUxXJNRLhEiKyuLNm3a0L59ey655BI2b97Mq6++Ksnch3bt2sWuXd6VkxXe83cZ4VAmCT3Maa155513SEpKYtmyZYwePZp169bRoIHU1PC1Ll260KVLF7PDCHvO6rbLwhjFpMsljP3666907tyZb775hhYtWvDOO+9w+eWXmx2WEOUSiDLCoUoSehgqLCxk3LhxDBw4EIvFwpQpU+jUqZMU0xJhQxbGcE4SepjZvn07KSkpfP/999x7771MmjSJWrVqmR2WECIApMkWJs6cOcPgwYO57rrr2LNnDzNnzmT+/PmSzIWIINJCDwPff/89KSkpbN++nccee4xx48YZWnle+NbAgQPNDkFEOEnoISw3N5eXX36ZsWPHcuGFF7JgwQLuvfdes8OKWHfeeafZIYgIJwk9RH3zzTd06tSJPXv20KVLF9544w2qV69udlgRLSMj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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import seaborn as sns\n", "import matplotlib.pyplot as plt\n", "plt.plot(df_2d['AUC'], df_2d['DEGREE_NULL_AUC'], 'o')\n", "plt.plot([0, 1], [0, 1], c='black')\n", "plt.axvline(x=df_2d['AUC'].mean(),c='black',ls='--')\n", "plt.axhline(y=df_2d['DEGREE_NULL_AUC'].mean(), c='black', ls='--')" ] }, { "cell_type": "code", "execution_count": null, "id": "b5b25ab4-ffd8-40ba-aed4-d9516fbfcaab", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 5 }