{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "1zSb-q70C9bz", "outputId": "98e7e591-cdf1-45de-8c96-809f956bc6d7" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Päivitetty 2024-07-23 / Aki Taanila\n" ] } ], "source": [ "from datetime import datetime\n", "print(f'Päivitetty {datetime.now().date()} / Aki Taanila')" ] }, { "cell_type": "markdown", "metadata": { "id": "gn5TjVbYC9b7" }, "source": [ "# Datan automaattinen analysointi - tulokset Excel-tiedostoon\n", "\n", "Tämän muistion avulla voit laskea automaattisesti frekvenssitaulukot, ristiintaulukoinnit, dikotomisten muuttujien yhteenvedot, tilastolliset tunnusluvut ja korrelaatiot. Tulokset kirjoitetaan Excel-tiedostoon.\n", "\n", "Sinun tehtäväksesi jää \n", "\n", "* Vaihda avattavan datan tilalle analysoitava data\n", "* Tarkista data ja tee tarvittavat muutokset\n", "* Määrittele analysoitavat muuttujat **Käyttäjän määrittelyt**-otsikon alla." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "LEtZ87QxC9b_", "scrolled": true }, "outputs": [], "source": [ "# Analysoinnissa käytettävät Python-paketit\n", "import numpy as np\n", "import pandas as pd\n", "from scipy.stats import chi2_contingency, ttest_ind, pearsonr" ] }, { "cell_type": "markdown", "metadata": { "id": "qkD_enqwC9cA" }, "source": [ "## Datan avaaminen\n", "\n", "Esimerkkinä käyttämäni data osoitteessa https://taanila.fi/data1.xlsx. Datan tilalle voit vaihtaa toisen datan.\n", "\n", "info()-listauksesta näet\n", "* datan rivien määrän\n", "* muuttujien nimet\n", "* muuttujakohtaiset havaintojen lukumäärät\n", "* muuttujien tyypit (int64 tarkoittaa kokonaislukua ja float64 liukulukua)." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "kL_YV0qAC9cC", "outputId": "073f293e-a24c-4da4-9fe3-ec2dc028b938" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 82 entries, 0 to 81\n", "Data columns (total 16 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 nro 82 non-null int64 \n", " 1 sukup 82 non-null int64 \n", " 2 ikä 82 non-null int64 \n", " 3 perhe 82 non-null int64 \n", " 4 koulutus 81 non-null float64\n", " 5 palveluv 80 non-null float64\n", " 6 palkka 82 non-null int64 \n", " 7 johto 82 non-null int64 \n", " 8 työtov 81 non-null float64\n", " 9 työymp 82 non-null int64 \n", " 10 palkkat 82 non-null int64 \n", " 11 työteht 82 non-null int64 \n", " 12 työterv 47 non-null float64\n", " 13 lomaosa 20 non-null float64\n", " 14 kuntosa 9 non-null float64\n", " 15 hieroja 22 non-null float64\n", "dtypes: float64(7), int64(9)\n", "memory usage: 10.4 KB\n" ] } ], "source": [ "df = pd.read_excel('https://taanila.fi/data1.xlsx')\n", "df.info()" ] }, { "cell_type": "markdown", "metadata": { "id": "ciIUxY3PC9cD" }, "source": [ "## Käyttäjän määrittelyt\n", "\n", "Määrittele listoina kategoriset, määrälliset (kvantit) ja dikotomiset muuttujat. Tarvittaessa sama muuttuja voi olla useammassakin listassa. Muuttujan voi jättää myös pois listoista, jolloin sitä ei analysoida.\n", "\n", "**Tärkeää: Jos kategoriset, kvantit tai dikotomiset -listaan ei tule muuttujia, niin jätä kuitenkin tyhjä lista** `[ ]`.\n", "\n", "Jos kategorisen muuttujan arvot ovat datassa numeroita, niin voit määritellä numeroita vastaavat tekstimuotoiset arvot listat-sanakirjana. Näin saat tekstimuotoiset arvot automaattisesti tulostaulukoihin. Kirjoita tekstimuotoiset arvot niitä vastaavien numeroarvojen mukaisessa järjestyksessä.\n", "\n", "**Tärkeää: Jos et määrittele tekstimuotoisia arvoja, niin jätä kuitenkin tyhjä listat-sanakirja** `listat = { }`\n", "\n", "Voit hyödyntää sarakenimien listaa (columns) omia listoja kirjoittaessa:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "gRtk_v0XC9cE", "outputId": "2fafa916-bfd8-4e8d-85f7-aa7d16e867c1" }, "outputs": [ { "data": { "text/plain": [ "Index(['nro', 'sukup', 'ikä', 'perhe', 'koulutus', 'palveluv', 'palkka',\n", " 'johto', 'työtov', 'työymp', 'palkkat', 'työteht', 'työterv', 'lomaosa',\n", " 'kuntosa', 'hieroja'],\n", " dtype='object')" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.columns" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "id": "spEuowLCC9cF" }, "outputs": [], "source": [ "# Tarkasteltavat muuttujat\n", "kategoriset = ['sukup', 'perhe', 'koulutus', 'johto', 'työtov', 'työymp', 'palkkat', 'työteht']\n", "kvantit = ['ikä', 'palveluv', 'palkka', 'johto', 'työtov', 'työymp', 'palkkat', 'työteht']\n", "dikotomiset = ['työterv', 'lomaosa', 'kuntosa', 'hieroja']\n", "\n", "# Esimerkkidatassa on useita samalla asteikolla mitattuja muuttujia\n", "# Toiston välttämiseksi tallennetaan asteikko listana\n", "tyytyvaisyys = ['Erittäin tyytymätön', 'Tyytymätön','Ei tyytymätön eikä tyytyväinen',\n", " 'Tyytyväinen', 'Erittäin tyytyväinen']\n", "\n", "# Tekstiarvot df:n kategorisille muuttujille, joiden arvot datassa koodattu numeroina\n", "listat = {'sukup':['Mies', 'Nainen'],\n", " 'perhe':['Perheetön', 'Perheellinen'],\n", " 'koulutus':['Peruskoulu', '2. aste', 'Korkeakoulu', 'Ylempi korkeakoulu'],\n", " 'johto':tyytyvaisyys,\n", " 'työtov':tyytyvaisyys,\n", " 'työymp':tyytyvaisyys,\n", " 'palkkat':tyytyvaisyys,\n", " 'työteht':tyytyvaisyys}" ] }, { "cell_type": "markdown", "metadata": { "id": "-TJ3emSFC9cG" }, "source": [ "## Arvojen tarkistus\n", "\n", "Seuraavan solun koodin avulla voit tarkistaa kategoristen ja dikotomisten muuttujien arvot.\n", "\n", "- Kokonaislukutyyppisten (int) muuttujien arvot näytetään sellaisenaan.\n", "- Liukulukutyyppisten muuttujien arvot näytetään desimaalipisteellä varustettuna, esimerkiksi 1. 2. jne.\n", "- nan tarkoittaa puuttuvaa arvoa.\n", "- Numeerinen muuttuja, jolla on puuttuvia arvoja on aina liukulukutyyppinen, koska kokonaislukutyyppisille muuttujille puuttuvaa arvoa ei ole määritelty.\n", "- Jos huomaat asiaan kuulumattomia arvoja, niin tee dataan tarvittavat korjaukset." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "f6kVqnY1C9cH", "outputId": "88cd7a46-cf0e-40de-c77b-b61b1efba7a1" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sukup [1 2]\n", "perhe [1 2]\n", "koulutus [ 1. 2. 3. 4. nan]\n", "johto [1 2 3 4 5]\n", "työtov [ 2. 3. 4. 5. nan]\n", "työymp [1 2 3 4 5]\n", "palkkat [1 2 3 4 5]\n", "työteht [1 2 3 4 5]\n", "työterv [ 1. nan]\n", "lomaosa [ 1. nan]\n", "kuntosa [ 1. nan]\n", "hieroja [ 1. nan]\n" ] } ], "source": [ "for var in df[kategoriset + dikotomiset]:\n", " try:\n", " print(var, np.unique(df[var]))\n", " except:\n", " print(var, pd.unique(df[var]))" ] }, { "cell_type": "markdown", "metadata": { "id": "GcniaLFRC9cI" }, "source": [ "## Excelin alustus\n", "\n", "Voit halutessasi vaihtaa Excel-tiedoston (**pika.xlsx**) nimen.\n", "\n", "**Tärkeää: Jos samanniminen Excel-tiedosto on jo olemassa niin menetät sen, koska koodi ylikirjoittaa tiedoston kysymättä.**" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "id": "D6_gO7I_C9cI" }, "outputs": [], "source": [ "# Excel-tiedoston luonti\n", "writer = pd.ExcelWriter('pika.xlsx', engine='xlsxwriter')\n", "workbook = writer.book\n", "\n", "# Muotoilut\n", "decimal3_format = workbook.add_format({'num_format':'0.000'})\n", "percent_format = workbook.add_format({'num_format':'0.0 %'})\n", "header_format = workbook.add_format({'align': 'right', 'bottom': 1})\n", "title_format = workbook.add_format({'align': 'left', 'bottom':1})\n", "index_format = workbook.add_format({'align': 'left', 'border':0})\n", "bold_format = workbook.add_format({'bold': True})\n", "right_format = workbook.add_format({'align':'right'})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tulosten laskenta\n", "\n", "Tulosten laskenta toistuu samanlaisena usealle muuttujalle. Tämän vuoksi seuraavassa käytetään valmiita funktioita (**def**), joita kutsutaan jokaisen laskettavan muuttujan kohdalla.\n", "\n", "Tulosten kirjoittaminen Exceliin ja muotoilu Excelissä muodostaa ison osan koodista. Tässä käytetään **xlsxwriter**ia, josta löydät lisätietoa osoitteesta https://xlsxwriter.readthedocs.io/ " ] }, { "cell_type": "markdown", "metadata": { "id": "GinxgcCnC9cJ" }, "source": [ "### Frekvenssitaulukot kategorisille muuttujille\n", "\n", "- Laskee frekvenssitaulukot df:n muuttujille, joiden nimet löytyvät kategoriset-listasta.\n", "- Taulukoihin lisätään muuttujien tekstimuotoiset arvot, jotka löytyvät listat-sanakirjasta.\n", "- Jos sanakirjan arvojen lukumäärä ei ole sama kuin frekvenssitaulukossa esiintyvien arvojen lukumäärä, niin tekstimuotoisia arvoja ei listätä frekvenssitaulukkoon." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "cAkplQ_DC9cK" }, "outputs": [], "source": [ "def frekv(muuttuja):\n", "\n", " '''Frekvenssitaulukko df:n muuttujalle muuttuja'''\n", "\n", " df1 = pd.crosstab(df[muuttuja], columns='f')\n", " df1.columns.name = ''\n", " n = df1['f'].sum()\n", " df1['%'] = df1['f']/n\n", "\n", " # muuttujan tekstimuotoiset arvot\n", " if muuttuja in listat.keys():\n", " if len(listat[muuttuja]) == len(df1.index):\n", " df1.index = listat[muuttuja]\n", "\n", " df1.loc['Yhteensä'] = df1.sum()\n", "\n", " return df1\n", "\n", "\n", "if kategoriset:\n", " rivi = 2 # Excelin rivinumero, johon seuraava taulukko kirjoitetaan\n", " ws1 = workbook.add_worksheet('frekvenssitaulukot')\n", " for muuttuja in kategoriset:\n", "\n", " df1 = frekv(muuttuja)\n", "\n", " df1.to_excel(writer, sheet_name='frekvenssitaulukot', startrow=rivi)\n", " ws1.write(rivi, 0, muuttuja, title_format)\n", " for sarake, arvo in enumerate(df1.columns):\n", " ws1.write(rivi, sarake+1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(df1.index):\n", " ws1.write(rivi+rivinumero+1, 0, arvo, index_format)\n", "\n", " rivi = rivi+df1.shape[0] + 2\n", "\n", " ws1.set_column('C:C', cell_format=percent_format)\n", " ws1.write(0, 0, 'Kategoristen muuttujien frekvenssitaulukot', bold_format)" ] }, { "cell_type": "markdown", "metadata": { "id": "2GT2GVQKC9cK" }, "source": [ "### Ristiintaulukoinnit kategorisille muuttujille\n", "\n", "- Laskee ristiintaulukoinnit df:n muutujille, jotka löytyvät kategoriset-listasta.\n", "- Ristiintaulukointien prosentit ovat prosentteja sarakkeiden kokonaismääristä (taulukoissa näkyvät n-arvot).\n", "- Taulukoihin lisätään muuttujien tekstimuotoiset arvot, jotka löytyvät listat-sanakirjasta.\n", "- Jos sanakirjan arvojen lukumäärä ei ole sama kuin ristiintaulukoinnissa esiintyvien arvojen lukumäärä, niin tekstimuotoisia arvoja ei listätä taulukkoon.\n", "- Ristiintaulukoinnin viereen lasketaan khiin neliö -testimuuttuja, khiin neliö -testin p-arvo ja vapausasteiden lukumäärä." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "id": "Fe7_YqG3C9cK" }, "outputs": [], "source": [ "def risti(muuttuja1, muuttuja2):\n", "\n", " '''Ristiintaulukointi df:n muuttujille muuttuja1 ja muuttuja2.\n", " Funktio palauttaa ristiintaulukoinnin lisäksi n-arvot ja khiin neliö -testin tuloksen.'''\n", "\n", " khi_testi = chi2_contingency(pd.crosstab(df[muuttuja1], df[muuttuja2]))\n", " df1 = pd.crosstab(df[muuttuja1], df[muuttuja2], margins=True)\n", " df2 = pd.crosstab(df[muuttuja1], df[muuttuja2], margins=True, normalize='columns')\n", "\n", " # muuttujien tekstimuotoiset arvot\n", " if muuttuja1 in listat.keys():\n", " if len(listat[muuttuja1]) == len(df1.index) - 1:\n", " df1.index = listat[muuttuja1] + ['Yhteensä']\n", " df2.index = listat[muuttuja1]\n", " else:\n", " df1.rename(index={'All':'Yhteensä'}, inplace=True)\n", " else:\n", " df1.rename(index={'All':'Yhteensä'}, inplace=True) \n", " if muuttuja2 in listat.keys():\n", " if len(listat[muuttuja2]) == len(df1.columns) - 1:\n", " df1.columns = listat[muuttuja2] + ['Yhteensä']\n", " df2.columns = listat[muuttuja2] + ['Yhteensä']\n", " else:\n", " df1.rename(columns={'All':'Yhteensä'}, inplace=True)\n", " df2.rename(columns={'All':'Yhteensä'}, inplace=True)\n", " else:\n", " df1.rename(columns={'All':'Yhteensä'}, inplace=True)\n", " df2.rename(columns={'All':'Yhteensä'}, inplace=True)\n", "\n", " n_arvot = ['n']\n", " for i in range(df1.shape[1]):\n", " n_arvot.append(df1.iloc[-1, i])\n", "\n", " return df2, n_arvot, khi_testi\n", "\n", "\n", "if len(kategoriset) > 1:\n", " rivi = 3 # Excelin rivinumero, johon seuraava taulukko kirjoitetaan\n", " ws2 = workbook.add_worksheet('ristiintaulukoinnit')\n", " for muuttuja1 in kategoriset:\n", " for muuttuja2 in kategoriset:\n", " if muuttuja1 != muuttuja2:\n", "\n", " df2, n_arvot, khi_testi = risti(muuttuja1, muuttuja2)\n", "\n", " df2.to_excel(writer, sheet_name='ristiintaulukoinnit', startrow=rivi)\n", " for sarake, n in enumerate(n_arvot):\n", " ws2.write(rivi+df2.shape[0]+1, sarake, n)\n", " ws2.write(rivi, 0, muuttuja1, title_format)\n", " ws2.write(rivi-1, 1, muuttuja2)\n", " for sarake, arvo in enumerate(df2.columns):\n", " ws2.write(rivi, sarake + 1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(df2.index):\n", " ws2.write(rivi+rivinumero+1 , 0, arvo, index_format)\n", " for rivinumero in range(rivi+1, rivi+df2.shape[0]+1):\n", " ws2.set_row(rivinumero, cell_format=percent_format)\n", "\n", " ws2.write(rivi, df2.shape[1]+2, f'khiin neliö = {khi_testi[0]:.3f}, p-arvo = {khi_testi[1]:.3f}, vapausasteet = {khi_testi[2]}')\n", " ws2.write(rivi+1, df2.shape[1]+2, f'Alle viiden suuruisia odotettuja frekvenssejä {((khi_testi[3]<5).sum()/khi_testi[3].size*100).round(2)} %')\n", "\n", " rivi = rivi+df2.shape[0] + 4\n", "\n", " ws2.write(0, 0, 'Kategoristen muuttujien ristiintaulukoinnit', bold_format)" ] }, { "cell_type": "markdown", "metadata": { "id": "jyz2bL5oC9cL" }, "source": [ "### Dikotomisten muuttujien yhteenvedot\n", "\n", "- Laskee dikotomiset-listasta löytyville muuttujille arvojen summan.\n", "- Oletuksena on että dikotomisella muuttujalla on vain arvoja 1 ja 0 (tai puuttuva arvo).\n", "- Prosentit lasketaan otoksen koosta (taulukossa näkyvä n-arvo)." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "id": "p_YpIxuiC9cM" }, "outputs": [], "source": [ "def dikot(dikotomiset):\n", "\n", " '''Frekvenssit dikotomiset-listasta löytyville df:n muuttujille'''\n", "\n", " df1 = df[dikotomiset].sum().to_frame('f').sort_values('f', ascending=False)\n", " n = df.shape[0]\n", " df1['% vastaajista'] = df1['f']/n\n", "\n", " return df1, n\n", "\n", "if dikotomiset:\n", " rivi = 2 # Excelin rivinumero, johon seuraava taulukko kirjoitetaan\n", " ws3 = workbook.add_worksheet('dikotomiset')\n", "\n", " df1, n = dikot(dikotomiset)\n", "\n", " df1.to_excel(writer, sheet_name='dikotomiset', startrow=rivi)\n", " ws3.write(rivi, 0, '', title_format)\n", " ws3.write(rivi+df1.shape[0]+1, 2, f'n = {n}', right_format)\n", " for sarake, arvo in enumerate(df1.columns.values):\n", " ws3.write(rivi, sarake+1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(df1.index.values):\n", " ws3.write(rivi+rivinumero+1 , 0, arvo, index_format)\n", "\n", " ws3.set_column('C:C', 12, cell_format=percent_format)\n", " ws3.write(0, 0, 'Dikotomisten muuttujien yhteenvedot', bold_format)" ] }, { "cell_type": "markdown", "metadata": { "id": "fxcVj_-BC9cM" }, "source": [ "### Kategoristen ristiintaulukointi dikotomisten muuttujien kanssa\n", "\n", "- Laskee dikotomiset-listan muuttujien arvojen summat prosentteina kategoristen muuttujien määräämistä ryhmistä (ryhmien koot näkyvät n-arvoissa).\n", "- Oletuksena on että dikotomisella muuttujalla on vain arvoja 1 ja 0 (tai puuttuva arvo)." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "id": "okG_nT0tC9cN" }, "outputs": [], "source": [ "def risti_dikot(muuttuja, dikotomiset):\n", "\n", " '''Ristiintaulukointi df:n muuttujan muuttuja ja dikotomiset-listan mukaisten\n", " dikotomisten muuttujien välille'''\n", "\n", " df1 = df.groupby(muuttuja)[dikotomiset].sum()\n", " dfn = pd.crosstab(df[muuttuja], 'f') # n-arvot\n", "\n", " # Prosenttien laskenta\n", " n_arvot = ['n']\n", " for i in range(df1.shape[0]):\n", " df1.iloc[i, :] = df1.iloc[i, :]/dfn.iloc[i, 0]\n", " n_arvot.append(dfn.iloc[i, 0])\n", "\n", " # kategorisen muuttujan tekstimutoiset arvot\n", " if muuttuja in listat.keys():\n", " if len(listat[muuttuja]) == len(df1.index):\n", " df1.index = listat[muuttuja]\n", "\n", " return df1.T, n_arvot\n", "\n", "\n", "if dikotomiset:\n", " if kategoriset:\n", " rivi = 3\n", " ws4 = workbook.add_worksheet('kategoriset+dikotomiset')\n", " for muuttuja in kategoriset:\n", "\n", " df1, n_arvot = risti_dikot(muuttuja, dikotomiset)\n", "\n", " df1.to_excel(writer, sheet_name='kategoriset+dikotomiset', startrow=rivi)\n", " ws4.write(rivi-1, 1, muuttuja)\n", " for sarake, n in enumerate(n_arvot):\n", " ws4.write(rivi+df1.shape[0]+1, sarake, n)\n", " ws4.write(rivi, 0, '', title_format)\n", " for sarake, arvo in enumerate(df1.columns.values):\n", " ws4.write(rivi, sarake + 1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(df1.index.values):\n", " ws4.write(rivi+rivinumero+1 , 0, arvo, index_format)\n", " for i in range(rivi+1, rivi+df1.shape[0]+1):\n", " ws4.set_row(i, cell_format=percent_format)\n", "\n", " rivi = rivi + df1.shape[0] + 4\n", "\n", " ws4.write(0, 0, 'Kategoristen muuttujien ristiintaulukoinnit dikotomisten kanssa', bold_format)" ] }, { "cell_type": "markdown", "metadata": { "id": "QRZ0MDgpC9cO" }, "source": [ "### Tilastolliset tunnusluvut ja tunnusluvut kategoristen muuttujien määräämissä ryhmissä\n", "\n", "- Laskee tilastolliset tunnusluvut kvantit-listasta löytyville muuttujille.\n", "- Tunnusluvut lasketaan myös kategoriset-listan muuttujien määräämissä ryhmissä.\n", "- Jos kategorinen muuttuja määrittää täsmälleen kaksi ryhmää, niin keskiarvojen viereen lasketaan kahden riippumattoman otoksen t-testi testimuuttuja ja p-arvo." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "id": "XhhcS7goC9cP" }, "outputs": [], "source": [ "tunnusluvut = ['Lukumäärä', 'Keskiarvo', 'Keskihajonta', 'Pienin', 'Alaneljännes',\n", " 'Mediaani', 'Yläneljännes', 'Suurin']\n", "\n", "def tunnu(kvantit):\n", "\n", " '''Laskee kvantit-listan sisältämien muuttujien tilastolliset tunnusluvut'''\n", "\n", " if len(kvantit) == 1:\n", " df1 = df[kvantit].describe().to_frame()\n", " else:\n", " df1 = df[kvantit].describe()\n", " df1.index = tunnusluvut\n", "\n", " return df1\n", "\n", "\n", "def risti_tunnu(muuttuja1, muuttuja2):\n", "\n", " '''Muuttujan muuttuja2 tunnuslukuja kategorisen muuttujan muuttuja1 määräämissä ryhmissä\n", " Jos kategorinen muuttuja määrittää täsmälleen kaksi ryhmää, niin funktio\n", " palauttaa myös kahden riippumattoman otoksen t-testin tuloksen.'''\n", "\n", " df1 = df.groupby(muuttuja1)[muuttuja2].describe().T\n", " df1.index = tunnusluvut\n", "\n", " if muuttuja1 in listat.keys():\n", " if len(listat[muuttuja1]) == len(df1.columns):\n", " df1.columns = listat[muuttuja1]\n", "\n", " kategoriat = df[muuttuja1].dropna().unique()\n", " if len(kategoriat) == 2:\n", " ryhma1 = df[muuttuja2][df[muuttuja1]==kategoriat[0]]\n", " ryhma2 = df[muuttuja2][df[muuttuja1]==kategoriat[1]]\n", " testi = ttest_ind(ryhma1, ryhma2, equal_var=False, nan_policy='omit')\n", " else:\n", " testi=False\n", "\n", " return df1, testi\n", "\n", "\n", "if kvantit:\n", " rivi = 2\n", " ws5 = workbook.add_worksheet('tunnusluvut')\n", "\n", " df1 = tunnu(kvantit)\n", "\n", " df1.to_excel(writer, sheet_name='tunnusluvut', startrow=rivi)\n", " ws5.write(rivi, 0, '', title_format)\n", " for sarake, arvo in enumerate(df1.columns.values):\n", " ws5.write(rivi, sarake+1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(df1.index.values):\n", " ws5.write(rivi+rivinumero+1, 0, arvo, index_format)\n", "\n", " if kategoriset:\n", " rivi = rivi + 11\n", " for muuttuja1 in kategoriset:\n", " for muuttuja2 in kvantit:\n", " if muuttuja1 != muuttuja2:\n", "\n", " df1, testi = risti_tunnu(muuttuja1, muuttuja2)\n", "\n", " df1.to_excel(writer, sheet_name='tunnusluvut', startrow=rivi)\n", " ws5.write(rivi-1, 1, muuttuja1)\n", " ws5.write(rivi, 0, muuttuja2, title_format)\n", " for sarake, arvo in enumerate(df1.columns.values):\n", " ws5.write(rivi, sarake+1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(df1.index.values):\n", " ws5.write(rivi+rivinumero+1 , 0, arvo, index_format)\n", "\n", " if testi != False:\n", " ws5.write(rivi+2, 4, f't = {testi[0]:.3f}, p-arvo = {testi[1]:.3f}')\n", "\n", " rivi = rivi+11\n", "\n", " ws5.set_column(0, 0, 12)\n", " ws5.write(0, 0, 'Määrällisten muuttujien tunnusluvut ja tunnusluvut kategoristen muuttujien määräämissä ryhmissä', bold_format)" ] }, { "cell_type": "markdown", "metadata": { "id": "1v3N4eT2C9cP" }, "source": [ "### Korrelaatiokertoimet määrällisille muuttujille\n", "\n", "- Laskee korrelaatiokertoimet kvantit-listan muuttujille.\n", "- Lisäksi lasketaan korrelaatioketoimiin liittyvät p-arvot ja n-arvot." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "id": "zGm0OCA9C9cQ" }, "outputs": [], "source": [ "def korre(kvantit):\n", "\n", " '''Laskee kvantit-listan sisältämien muuttujien väliset Pearsonin korrelaatiokertoimet sekä\n", " kertoimiin liittyvät p-arvot ja n-arvot.'''\n", "\n", " dfr = pd.DataFrame(index=df[kvantit].columns, columns=df[kvantit].columns).astype('float')\n", " dfp = pd.DataFrame(index=df[kvantit].columns, columns=df[kvantit].columns).astype('float')\n", " dfn = pd.DataFrame(index=df[kvantit].columns, columns=df[kvantit].columns)\n", " for muuttuja1 in df[kvantit]:\n", " for muuttuja2 in df[kvantit]:\n", " if muuttuja1 != muuttuja2:\n", " df_dropna = df.dropna(subset=[muuttuja1, muuttuja2])\n", " r, p = pearsonr(df_dropna[muuttuja1], df_dropna[muuttuja2])\n", " n = df_dropna.shape[0]\n", " dfr.loc[muuttuja1, muuttuja2] = r\n", " dfp.loc[muuttuja1, muuttuja2] = p\n", " dfn.loc[muuttuja1, muuttuja2] = n\n", " return dfr, dfp, dfn\n", "\n", "if kvantit:\n", " if len(kvantit) > 1:\n", " rivi = 2\n", " ws6 = workbook.add_worksheet('korrelaatiot')\n", "\n", " dfr, dfp, dfn = korre(kvantit)\n", "\n", " dfr.to_excel(writer, sheet_name='korrelaatiot', startrow=rivi)\n", " ws6.write(rivi, 0, '', title_format)\n", " for sarake, arvo in enumerate(dfr.columns.values):\n", " ws6.write(rivi, sarake+1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(dfr.index.values):\n", " ws6.write(rivi+rivinumero+1, 0, arvo, index_format)\n", " for rivinumero in range(rivi+1, rivi+dfr.shape[0]+1):\n", " ws6.set_row(rivinumero, cell_format=decimal3_format)\n", "\n", " rivi = rivi + dfr.shape[0] + 2\n", "\n", " dfp.to_excel(writer, sheet_name='korrelaatiot', startrow=rivi)\n", " ws6.write(rivi, 0, 'p-arvot', title_format)\n", " for sarake, arvo in enumerate(dfr.columns.values):\n", " ws6.write(rivi, sarake+1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(dfr.index.values):\n", " ws6.write(rivi+rivinumero+1, 0, arvo, index_format)\n", " for rivinumero in range(rivi+1, rivi+dfp.shape[0]+1):\n", " ws6.set_row(rivinumero, cell_format=decimal3_format)\n", "\n", " rivi = rivi + dfr.shape[0] + 2\n", "\n", " dfn.to_excel(writer, sheet_name='korrelaatiot', startrow=rivi)\n", " ws6.write(rivi, 0, 'n-arvot', title_format)\n", " for sarake, arvo in enumerate(dfr.columns.values):\n", " ws6.write(rivi, sarake+1, arvo, header_format)\n", " for rivinumero, arvo in enumerate(dfr.index.values):\n", " ws6.write(rivi+rivinumero+1, 0, arvo, index_format)\n", "\n", " ws6.write(0, 0, 'Määrällisten muuttujien väliset korrelaatiokertoimet', bold_format)" ] }, { "cell_type": "markdown", "metadata": { "id": "RDdDK52gC9cQ" }, "source": [ "## Excel-tiedoston sulkeminen\n", "\n", "**Tärkeää: Viimeisen solun suoritus on tärkeää, jotta tuotoksena syntynyt Excel-tiedosto on myöhemmin avattavissa**\n", "\n", "Jos tulostiedoston avaaminen Exceliin ei onnistu, niin todennäköisesti jokin koodisolu on antanut virheilmoituksen ja writer.close()-komento on jäänut suorittamatta. Suorita tällöin komento writer.close() seuraavasta solusta. Selvitä sen jälkeen mistä virheilmoitus johtui." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "id": "PizLcm5FC9cQ" }, "outputs": [], "source": [ "writer.close()" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.12.4" } }, "nbformat": 4, "nbformat_minor": 4 }