Mulla tuli vastaan kaksi kysymystä, joihin en tiennyt vastausta:
1. Miten SQL-serverissä saa tehtyä R-funktion, joka laskee annetusta aineistosta Cronbachin alfa-arvon? Mulla on esimerkkiaineisto ja sain sen laskettua kun kovakoodasin luvut kyselyyn:
EXECUTE sp_execute_external_script @language = N'R' , @script = N'a1=c(4,3,4,5,1,5,5,5,5,5,5,4,4,4,5,4,5,5,5,4,5,5,4,4,5,5,3,4,4,4,4,5,5,4,3,5,1,5,5,5,5,4,4,4,5,5,4,5,5,4,5,5,5,4,4,1,5,5,3,5,5,4,5,5,4,4,4,4,5,5,4,4,4,4,5,1,5,5,5,4,4,3,5,4,5,5,4,4,4,5,5,5,5,5,3,5,4,5,5,5,5,5,5,5,4,5,4,4,5,4,5,5,5,4,5,4,4,5,4,5,5,2,4,4,5,3,4,4,4,5,4,5,3,5,5,5,4,5,5,2,1,5,5,5,4,4,4,4,5,5,4,4,5) a2=c(4,4,4,5,5,5,5,5,4,4,4,4,4,5,5,5,5,5,5,4,5,4,4,5,5,5,4,4,5,4,5,5,5,4,4,4,1,5,5,4,5,3,4,4,4,5,5,5,5,5,5,5,5,5,4,1,4,5,4,4,4,5,5,4,5,5,4,4,4,4,4,3,5,4,5,5,5,5,4,4,4,2,4,5,4,5,5,4,2,5,5,4,4,5,4,5,5,5,4,4,5,4,4,5,4,5,4,3,4,5,5,5,4,4,5,2,2,2,4,5,4,3,5,4,5,3,4,5,4,5,4,5,4,5,4,4,5,5,5,4,1,5,5,4,4,4,4,4,4,5,4,4,4) a3=c(5,4,5,3,2,4,4,4,4,3,4,5,3,3,2,2,2,1,2,3,2,5,2,4,2,2,4,2,4,5,4,3,4,2,4,4,1,1,4,4,3,3,2,2,3,3,3,2,4,2,5,4,3,3,4,3,4,4,3,3,4,3,4,4,2,2,4,4,5,4,4,4,3,4,4,2,4,2,3,2,5,4,4,3,5,4,4,4,4,1,2,3,2,4,5,3,3,2,3,4,5,3,4,3,4,1,3,4,4,2,2,2,3,3,3,4,4,5,2,4,4,4,3,3,2,4,4,2,3,4,4,4,4,2,2,3,3,2,3,3,3,2,4,2,3,3,4,4,3,5,2,3,2) a4=c(2,4,2,2,2,2,2,4,2,4,2,4,2,2,2,2,2,1,1,2,2,1,2,1,2,4,1,1,2,4,2,2,2,1,2,2,1,1,2,2,2,4,5,2,1,1,2,1,2,4,3,4,2,4,1,4,3,2,2,2,1,2,1,2,4,5,2,2,2,1,2,2,3,2,2,4,1,1,2,2,3,5,2,2,2,1,2,4,2,5,1,2,1,3,2,4,2,2,2,4,4,1,2,1,2,1,2,4,2,2,4,2,2,3,2,2,2,2,4,1,4,2,2,2,2,2,2,4,2,3,2,4,3,2,2,2,2,4,1,2,2,2,2,1,5,2,4,5,2,2,2,3,1) a5=c(5,5,5,5,5,5,4,5,3,4,5,4,5,5,5,5,5,5,5,4,5,5,4,5,5,4,5,4,5,5,5,5,4,5,4,5,5,5,5,5,5,5,5,4,5,5,5,5,1,4,5,5,5,4,5,5,5,5,4,5,5,5,5,5,5,5,5,4,5,5,5,5,4,4,5,5,5,5,5,5,5,3,5,5,5,5,5,5,4,5,5,5,5,4,4,4,5,5,5,5,1,5,4,5,5,4,4,5,5,5,4,5,1,4,5,5,5,5,4,5,2,4,1,5,5,4,5,5,4,5,1,4,4,5,5,5,4,5,5,5,5,5,4,5,4,4,4,4,5,4.56579,5,4,4) a6=c(2,2,3,4,4,4,3,4,3,3,2,4,4,5,5,5,4,4,5,3,4,4,4,5,4,4,2,2,4,4,4,5,5,5,3,2,1,4,4,3,2,2,4,4,4,4,4,4,4,4,5,1,4,4,4,5,4,5,2,3,1,4,4,4,4,4,3,2,3,3,4,3,4,2,5,4,4,5,4,4,4,2,2,4,4,2,1,4,3,5,5,4,4,4,4,5,3,5,4,4,5,3,2,3,4,4,4,2,4,4,4,5,4,4,4,3,3,3,4,4,4,2,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,5,5,4,5,4,4,4,4,4,3,4,4,2,4,2,5) a7=c(2,2,4,1,2,1,2,2,2,4,2,2,3,2,1,2,2,1,1,2,4,2,1,2,2,2,2,1,5,4,1,1,4,1,3,2,5,2,2,2,4,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,3,1,3,2,1,2,1,2,2,2,2,3,2,2,2,4,2,2,2,2,4,2,3,1,2,3,3,2,4,1,2,2,2,1,1,2,1,2,3,2,1,1,2,2,1,2,3,2,2,1,2,2,2,2,2,1,2,3,2,2,4,1,3,2,2,2,2,3,2,2,1,1,2,3,3,3,2,1,2,2,2,1,5,1,2,2,1,1,3,2,2,3,2,4,2,3,2) a8=c(4,5,5,4,4,4,4,5,4,3,4,5,4,5,5,4,5,5,5,4,4,5,5,4,4,5,3,4,5,4,4,5,5,4,4,4,1,4,5,5,3,2,4,3,4,5,5,1,5,4,5,5,4,5,4,5,4,5,3,5,5,4,5,3,5,4,5,4,5,4,4,3,4,4,4,4,4,4,5,4,4,2,4,4,4,4,4,4,3,5,4,4,4,4,3,4,4,5,4,5,5,4,3,5,4,5,4,2,4,4,4,5,4,4,4,4,5,5,4,5,5,3,4,4,4,4,5,4,4,4,4,4,3,5,4,5,4,5,5,4,5,5,5,5,3,4,2,4,4,1,5,4,4) a9=c(2,1,1,1,1,2,2,1,1,2,4,2,2,1,1,1,2,1,1,3,2,1,1,1,1,1,2,2,1,1,2,1,1,1,2,1,5,1,2,1,1,3,2,2,2,2,1,2,1,2,1,2,2,2,2,1,1,1,4,2,1,2,2,2,2,2,2,2,2,1,1,3,1,1,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,2,2,1,1,2,1,1,2,1,2,2,2,2,1,1,1,3,4,2,2,2,2,1,2,2,1,3,2,3,2,2,2,2,2,2,2,4,2,2,2,3,2,2,1,1,2,2,1,1,2,1,2,1,1,3,2,2,2,1,1,2,2,1) a10=c(5,4,4,4,5,5,5,4,5,4,4,4,3,5,5,4,4,5,5,4,4,5,3,5,4,5,4,4,5,4,4,5,4,4,5,4,1,4,4,4,5,3,4,4,3,5,4,4,5,5,4,4,4,4,4,5,4,4,4,4,5,4,5,4,5,4,4,4,3,4,4,4,5,3,4,4,4,5,5,5,4,4,4,4,4,5,5,4,3,5,4,4,5,4,4,5,4,4,4,5,5,3,4,3,4,5,5,4,5,4,4,4,5,4,4,4,4,2,4,4,4,4,5,3,4,4,4,4,4,4,3,4,4,4,4,3,4,5,5,4,5,4,4,4,4,4,4,4,4,4,4,3,4) a11=c(4,4,5,4,4,3,4,4,3,4,4,4,3,4,5,4,4,5,4,3,4,4,4,5,4,5,4,4,5,4,3,5,5,4,4,4,5,4,4,4,5,3,4,4,4,4,4,4,4,4,5,2,5,4,4,5,3,5,3,5,5,4,5,3,4,5,4,4,4,4,2,4,4,2,4,4,4,4,5,4,4,4,3,4,4,5,4,5,3,5,4,5,4,4,3,4,4,5,4,4,5,4,3,4,3,4,4,3,5,4,4,5,5,4,5,4,4,3,3,4,4,4,4,3,5,4,4,4,4,4,3,4,5,5,4,4,4,5,5,4,5,4,4,4,4,4,4,3,5,4,3,4,4) a12=c(2,4,4,2,1,2,2,2,2,4,4,3,2,2,1,1,2,1,1,3,2,2,2,2,2,2,2,2,3,2,2,1,1,1,3,1,5,3,2,2,4,3,2,2,2,1,2,1,2,2,3,1,2,2,1,1,2,1,3,2,3,1,1,2,2,3,1,1,3,4,2,3,2,2,2,2,2,4,2,2,1,2,2,2,2,2,2,2,4,1,1,2,1,2,2,2,1,2,2,3,1,2,3,2,2,1,3,1,1,2,2,2,2,1,1,2,4,2,1,2,2,2,3,2,2,2,1,2,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,1,2,2,4,3,2,2,2,3,3) a13=c(4,3,3,2,2,2,2,2,2,4,4,3,2,4,1,2,2,1,1,2,2,2,2,2,2,2,4,2,4,1,2,1,1,1,3,1,1,1,2,4,4,2,2,2,3,1,2,2,2,2,3,3,2,2,1,1,1,1,3,2,3,1,1,2,1,2,1,1,2,4,2,2,2,1,2,2,2,3,2,1,1,2,1,2,2,1,1,2,4,1,1,1,2,2,4,2,1,1,3,2,1,2,2,2,2,1,3,1,1,2,1,2,2,2,2,2,2,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1,2,2,2,1,1,2,1,2,2,1,2,2,3,3,1,1.99342,2,3,2) a14=c(4,3,5,5,5,4,4,5,4,4,2,4,4,5,5,5,5,5,5,4,4,4,4,5,5,5,2,5,5,4,3,5,4,5,4,5,5,4,4,4,5,4,4,5,3,5,4,2,4,5,5,4,4,4,4,5,4,5,4,5,5,4,5,4,5,4,4,5,5,5,5,4,3,4,4,4,4,5,5,5,5,4,5,4,5,4,5,4,3,5,3,4,4,5,3,5,4,5,4,4,5,4,4,5,4,4,4,3,5,5,4,5,5,4,5,2,5,3,3,4,2,2,5,4,4,4,5,4,4,2,4,4,3,5,4,4,4,5,5,4,5,4,4,4,3,4,4,3,5,5,4,4,5) a15=c(2,2,2,2,2,1,4,2,3,4,3,2,2,2,1,1,2,1,2,2,1,1,1,2,2,4,3,4,3,4,1,1,5,1,2,2,1,2,1,2,2,1,2,1,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,1,1,3,1,2,2,1,2,1,2,2,2,3,3,2,2,4,2,1,2,2,2,2,2,2,2,1,1,1,1,1,2,1,4,2,1,1,1,1,2,4,2,2,2,2,2,1,2,4,2,2,2,2,1,2,1,2,3,1,2,2,1,2,2,2,2,3,2,4,1,2,2,2,2,4,2,1,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,1) a16=c(2,3,4,4,4,4,5,4,3,3,2,5,4,4,5,4,4,5,5,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,4,4,1,4,4,4,2,3,4,3,4,4,3,1,4,4,4,5,4,4,4,5,3,5,3,4,4,3,5,4,4,4,4,3,3,3,2,4,4,2,4,4,4,4,4,5,4,3,3,4,4,4,4,4,4,5,4,4,5,4,2,4,4,5,4,4,4,3,4,4,3,4,4,4,3,4,4,4,5,3,4,3,3,5,4,4,4,2,3,4,4,4,4,5,4,3,4,4,4,4,4,4,4,5,5,3,2,4,4,5,3,4,3,4,5,3.82237,4,4,4) a17=c(4,4,3,5,4,5,4,4,3,4,4,5,4,4,5,4,5,3,5,3,4,4,4,4,3,4,5,4,4,4,3,5,5,4,3,4,1,4,4,4,3,3,4,4,4,4,4,1,4,4,5,5,4,3,4,5,4,5,4,5,5,4,4,4,4,4,4,3,4,2,4,4,4,2,3,4,4,4,4,4,3,3,3,4,3,4,2,5,3,5,5,4,4,4,2,5,4,4,4,4,4,4,4,4,3,5,4,2,3,4,4,2,3,3,4,4,3,5,3,5,5,4,4,4,4,4,4,5,4,3,4,3,3,4,4,4,4,4,5,4,3,4,4,5,4,4,4,3,5,3,3,4,4) a18=c(4,3,4,4,5,3,3,3,4,3,3,3,4,4,4,5,3,4,5,3,2,3,3,4,4,3,2,4,3,3,4,2,4,4,3,4,1,3,3,4,5,2,4,4,3,3,4,3,4,3,5,2,4,4,4,3,3,5,3,2,4,4,4,4,5,3,3,4,2,4,4,3,4,4,4,4,4,3,4,4,4,4,3,4,4,4,4,4,2,3,3,3,4,3,3,4,4,2,3,3,5,3,3,4,2,2,3,2,4,3,4,5,2,4,4,2,4,2,5,4,2,2,4,3,3,3,4,3,3,3,3,4,4,4,3,3,3,1,5,4,3,4,4,4,3,2,3,3,2,5,4,3,3) a19=c(4,4,4,5,5,4,5,3,4,3,4,3,4,5,2,5,5,5,4,4,4,4,4,4,5,5,2,4,5,4,5,5,5,5,4,5,1,5,4,3,5,3,4,4,4,4,4,1,5,4,4,4,4,5,5,5,4,5,4,4,4,4,5,4,5,4,3,5,5,5,3,4,4,4,4,5,4,4,5,5,3,4,4,4,4,4,5,5,2,5,5,4,5,4,2,5,5,4,4,4,4,5,4,5,3,5,4,3,4,4,4,5,5,3,4,3,5,2,5,4,4,2,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,5,5,4,4,4,5,4,3,4,3,2,4,4,5,4) a20=c(5,5,5,5,5,5,4,5,3,4,5,4,5,5,5,5,5,5,5,4,5,5,4,5,5,4,5,4,5,5,5,5,4,5,4,5,5,5,5,5,5,5,5,4,5,5,5,5,1,4,5,5,5,4,5,5,5,5,4,5,5,5,5,5,5,5,5,4,5,5,5,5,4,4,5,5,5,5,5,5,5,3,5,5,5,5,5,5,4,5,5,5,5,4,4,4,5,5,5,5,1,5,4,5,5,4,4,5,5,5,4,5,1,4,5,5,5,5,4,5,2,4,1,5,5,4,5,5,4,5,1,4,4,5,5,5,4,5,5,5,5,5,4,5,4,4,4,4,5,4.56579,5,4,4) options(warn=-1);a=cbind(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) library(psych); result = tryCatch(alpha(a), warning = function(w) {tryCatch(alpha(a,check.keys=TRUE),warning = function(w) { print("Error, you need some other way to estimate the reliability of a psychometric test!" ) })})'
Mutta miten tuon saisi yleistettyä datalle, joka haettaisiin tietystä taulusta? Esimerkiksi muuttujia ai voi olla eri määrä ja lukujen määrä annetussa sarakkeessa voi olla eri kuin tässä esimerkissä. Kuulemma kysely pitäisi tehdä ilman SQL-serverin ulkoista kieltä. En tiennyt aluksi tätä ja tein yllä olevan kyselyn C#:lla. Lisäksi kyselyssä pitäisi täyttää tietylle likert-asteikon välille kuulumattomat arvot sarakekohtaisilla keskiarvoilla, esimerkiksi tässä vaikkapa 3.82237 on laskettu keskiarvona muista sarakkeen luvuista.
2. Onko yllä olevassa R-koodissa virhe, kun siinä käsitellään kaksi sisäkkäistä virhetilannetta samannimisissä funktioissa w. Saako näin tehdä R:ssä vai pitäisikö funktiot nimetä vaikka w1 ja w2?
Imho, aika erikoinen setti SQL:n laskettavaksi. Siinä varmaan ihan ensiksi kannattaa miettiä taulurakenne tosiaan datalle jotta kysely saadaan inhimilliseen nopeuteen ja toiseksi miettiä, onko laskeminen nopeampaa kyselyn tuloksista koodin päässä, ja unohtaa koko laskutoimitus tietokantaserverillä.
jos muuttujia on dynaaminen määrä, on syytä joko käyttää A) joka tiedolle omaa riviä tai B) yhdistää muuttujadata yhteen sarakkseen rivillä foobar (esim taulukkona). Mikäli itse laskenta tapahtuu serverillä, poissuljetaan muut mallit, kuten tiedon tallentaminen vaikka jsonina (ellei sitte kyse ole noSQL -tietokannasta, kuten mongosta, mutta nythän kysymys koski vain SQL serveriä).
Sinuna tekisin n. kpl funktioita, joita kutsuttaisiin systemaattisesti tarvejärjestyksessä
1. Julistetaan muuttuja @a_variables sekä @c_bindVariable
2. for loopissa kutsutaan selectillä taulu(j)a, joista c -funktioon annetut arvot löytyy.
jokaisen loopin sisällä suoritetaan seuraavat funktiot:
loop step 1) funktio joka palauttaa taulu -tyyppisenä (https://docs.microsoft.com/en-us/sql/relational-databases/tables/use-table-valued-parameters-database-engine) halutut a1-ax arvot, yhden a muuttujan kerrallaan, annetun ehdon mukaisesti
- kutsutaan annetuilla parametreilla, jotka erottaa halutut a1-ax toisistaan
- palauttaa yhden table -tyyppisen tulon, jossa yhdellä rivillä yksi arvo
loop step 2) funktio, joka ottaa vastaan yhden yhden table tyyppisen parametrin sekä indeksin, ja palauttaa siitä merkkijonon 'a{index tässä}=c(1,2,3.....4)'
loop step 3) lisätään saatu merkkijono @a_variables muuttujaan
loop step 4) lisätään @c_bindVariable muuttujaan ',a' + index (loopin indeksi ,ei pilkkua jos index == 0)
3. asetetaan tiedot @script muuttujaan jota käytetään external script kutsussa
@script = @a_variables + 'options(warn=-1);' + 'a=cbind(' + @c_bindVariable + ');' + 'library(psych);' + 'result = alpha(a);';
Töissä ei noin vaan unohdeta lasku serverillä jos pomo käskee. Mulle tuli nyt uusi ongelma kyseisessä projektissa. Mulla on datat taulussa. Miten saan luettua datat siten, että voin käyttää niitä R:n puolella SQL-serverissä? Ideana olisi tehdä analyysiä kuten sivulla https://docs.microsoft.com/en-us/sql/advanced-analytics/tutorials/sql-server-r-tutorials mutta en saa muutettua dataa kannasta R:n ymmärtämään muotoon.
Eli jos vaikka
EXECUTE sp_execute_external_script @language = N'R' , @script = N' OutputDataSet <- InputDataSet;' , @input_data_1 = N'SELECT ky1 FROM Vuodet;'
palauttaa
4 3 4 5 1 ... 4 4 5
niin miten saisin tehtyä tuosta koodirivin
a1=c(4,3,4,5,1,...,4,4,5)
tuolla ylläolevalla tavalla, mistä jo mainitsinkin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.