R: Daten einlesen und analysieren

Aktualisiert:

5 Minuten zum Lesen

Über das Einlesen von Daten aus einer Datei und das Analysieren der Daten.

Daten einlesen

Um einmal das Einlesen von Daten zu demonstrieren, wurden in dem R-Kurs die daten von movielens.org verwendet. Kurz dazu ein Auszug aus der README, dann sieht man, wozu die Daten verwendet wurden und werden.

MovieLens data sets were collected by the GroupLens Research Project at the University of Minnesota.

This data set consists of:

  • 100,000 ratings (1-5) from 943 users on 1682 movies.
  • Each user has rated at least 20 movies.
  • Simple demographic info for the users (age, gender, occupation, zip)

The data was collected through the MovieLens web site (movielens.umn.edu) during the seven-month period from September 19th, 1997 through April 22nd, 1998. This data has been cleaned up - users who had less than 20 ratings or did not have complete demographic information were removed from this data set. Detailed descriptions of the data file can be found at the end of this file.

Hier wird nur die User-Datei u.user verwendet. Daran kann man einfache statistische Berechnungen durchführen und ein bißchen in R spielen.

Als erstes werden die Daten aus der Datei in einen dataframe eingelesen und, um sie zu untersuchen, verschiedene Kennwerte und Daten aufgerufen.

# Dateihandle zuweisen
u.user <- "/path/to/data/file/u.user"
# Header benennen
header <- c("userId","age","gender","occupation","zipCode")
# Daten in eine Tabelle einlesen
userInfo <- read.table(u.user,header = FALSE, sep ="|", quote = "\"'",col.names = header)
# Die Tabelle ist ein dataframe
class(userInfo)
[1] "data.frame"
head(userInfo,10)
# Abrufen von Tabellenzellen
userInfo[2:5,1:2]
userInfo[2:5,c(1,3:4)]
userInfo$age[1:10]
 [1] 24 53 23 24 33 42 57 36 29 53
class(userInfo$gender)
[1] "factor"
length(levels(userInfo$occupation))
[1] 21
levels(userInfo$occupation)
 [1] "administrator" "artist"        "doctor"        "educator"      "engineer"      "entertainment" "executive"    
 [8] "healthcare"    "homemaker"     "lawyer"        "librarian"     "marketing"     "none"          "other"        
[15] "programmer"    "retired"       "salesman"      "scientist"     "student"       "technician"    "writer"       

Gruppierungen und Ranges

Um zu bestimmen, in welchen Bereichen die Daten liegen, werden sie summiert oder gruppiert. Um sie später nach Altersgruppern zu clustern, werden Intervalle angelegt.

table(userInfo$occupation)

administrator        artist        doctor      educator      engineer entertainment     executive    healthcare     homemaker 
           79            28             7            95            67            18            32            16             7 
       lawyer     librarian     marketing          none         other    programmer       retired      salesman     scientist 
           12            51            26             9           105            66            14            12            31 
      student    technician        writer 
          196            27            45 
table(userInfo$gender)

  F   M 
273 670 
range(userInfo$age)
[1]  7 73
# Tabelle nach Altersbereichen clustern
bins <- seq(5,75,by=10)
intervals <- cut(userInfo$age,bins,right=FALSE)

Intervalle und Vorkommen

Hier werden die in den Intervallen liegenden Daten untersucht.

# Vorkommen in den Intervallen ist hier mal ausgeklammert
#intervals
table(intervals)
intervals
 [5,15) [15,25) [25,35) [35,45) [45,55) [55,65) [65,75) 
     11     223     310     194     142      51      12 
class(intervals)
[1] "factor"
# Legende für die Datenintervalle
namesInt <- paste("I", c(1:7), sep="")
legendInt <- data.frame(names(table(intervals)),namesInt)
names(legendInt) <- c("interval","name")
intervals <- cut(userInfo$age,bins,labels=namesInt,right=FALSE)
# Vorkommen des Alters in den Intervallen
ageFrame <- data.frame(intervals,userInfo$age)
ageFrame
names(ageFrame) <- c("I","Age")
ageFrame
# mal schauen, was der Table-Befehl hier macht
# Schon eine spannende Ausgabe: Vorkommen des einzelnen Alters in den Intervallen
table(ageFrame)
    Age
I     7 10 11 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
  I1  1  1  1  5  3  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I2  0  0  0  0  0  6  5 14 18 23 32 27 37 28 33  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I3  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 38 34 35 36 32 39 25 28 26 17  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I4  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 27 21 19 17 22 21 10 21 13 23  0  0  0  0  0  0  0
  I5  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 15 12 14 20 19 20 20
  I6  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I7  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
    Age
I    52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 68 69 70 73
  I1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I2  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I3  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I4  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I5  6 12  4  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  I6  0  0  0 11  6  9  3  3  9  3  2  3  2  0  0  0  0  0  0
  I7  0  0  0  0  0  0  0  0  0  0  0  0  0  3  1  2  2  3  1
# Vorkommen nach Geschlecht
genderFrame <- data.frame(intervals,userInfo$gender)
names(genderFrame) <- c("I","Gender")
genderFrame
table(genderFrame)
    Gender
I      F   M
  I1   5   6
  I2  63 160
  I3  79 231
  I4  69 125
  I5  48  94
  I6   8  43
  I7   1  11

Daten plotten

In R gibt es ziemlich viele Möglichkeiten, Daten grafisch auszugeben, wie ich beim Ausprobieren gesehen habe. Hier kann man einmal die Verteilung in den Altersintervallen nach Geschlecht sehen. Dann einmal einen Box-Plot der Verteilung des Alters der Teilnehmer in den Altersintervallen, was wahrscheinlich weniger sinnvoll ist. Und einen Box-Plot der Verteilung des Alters für Frauen und Männer.

# Legende für
legendInt
plot(table(genderFrame), type ="h", main = "Gender Histogram", xlab = "Intervals", ylab = "Male/Female" )

hist(userInfo$age,breaks = bins)

bwplot(Age ~ I, data = ageFrame,xlab = "Age from...to", ylab = "Age",main = "Age of participants")

gender2Frame <- data.frame(userInfo$age,userInfo$gender)
names(gender2Frame) <- c("Age","Gender")
boxplot(Age ~ Gender, data = gender2Frame,xlab = "Gender", ylab = "Age",main = "Gender of participants")

Zusammenfassende Statistik ausgeben

Hier werden zusammenfassende statistische Werte mit der aggregate-Funktion für Bereiche des dataframes ausgegeben.

aggregate(age ~ gender, userInfo, mean)
aggregate(age ~ gender + occupation, userInfo, mean)
occupationCounts <- aggregate(userId ~ occupation, userInfo, length)
head(occupationCounts[order(occupationCounts$userId, decreasing = TRUE),],3)
LS0tCnRpdGxlOiAiUjogUmVhZCBmaWxlcyBhbmQgYW5hbHl6ZSB0aGUgZGF0YSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IG5vbmUKICAgIGRmX3ByaW50OiBrYWJsZQogICAgaGlnaGxpZ2h0OiBweWdtZW50cwogICAgdGhlbWU6IGZsYXRseQogICAgdG9jOiB5ZXMKICBodG1sX2RvY3VtZW50OgogICAgaGlnaGxpZ2h0OiBweWdtZW50cwogICAga2VlcF9tZDogeWVzCi0tLQoKIyMgRGF0ZW4gZWlubGVzZW4KClVtIGVpbm1hbCBkYXMgRWlubGVzZW4gdm9uIERhdGVuIHp1IGRlbW9uc3RyaWVyZW4sIHd1cmRlbiBpbiBkZW0gUi1LdXJzIGRpZSBkYXRlbiB2b24gbW92aWVsZW5zLm9yZyB2ZXJ3ZW5kZXQuIEt1cnogZGF6dSBlaW4gQXVzenVnIGF1cyBkZXIgUkVBRE1FLCBkYW5uIHNpZWh0IG1hbiwgd296dSBkaWUgRGF0ZW4gdmVyd2VuZGV0IHd1cmRlbiB1bmQgd2VyZGVuLgoKPiBNb3ZpZUxlbnMgZGF0YSBzZXRzIHdlcmUgY29sbGVjdGVkIGJ5IHRoZSBHcm91cExlbnMgUmVzZWFyY2ggUHJvamVjdCBhdCB0aGUgVW5pdmVyc2l0eSBvZiBNaW5uZXNvdGEuCj4gCj4gVGhpcyBkYXRhIHNldCBjb25zaXN0cyBvZjoKPgo+ICogMTAwLDAwMCByYXRpbmdzICgxLTUpIGZyb20gOTQzIHVzZXJzIG9uIDE2ODIgbW92aWVzLiAKPiAqIEVhY2ggdXNlciBoYXMgcmF0ZWQgYXQgbGVhc3QgMjAgbW92aWVzLiAKPiAqIFNpbXBsZSBkZW1vZ3JhcGhpYyBpbmZvIGZvciB0aGUgdXNlcnMgKGFnZSwgZ2VuZGVyLCBvY2N1cGF0aW9uLCB6aXApCj4gCj4gVGhlIGRhdGEgd2FzIGNvbGxlY3RlZCB0aHJvdWdoIHRoZSBNb3ZpZUxlbnMgd2ViIHNpdGUgKG1vdmllbGVucy51bW4uZWR1KSBkdXJpbmcgdGhlIHNldmVuLW1vbnRoIHBlcmlvZCBmcm9tIFNlcHRlbWJlciAxOXRoLCAxOTk3IHRocm91Z2ggQXByaWwgMjJuZCwgMTk5OC4gVGhpcyBkYXRhIGhhcyBiZWVuIGNsZWFuZWQgdXAgLSB1c2VycyB3aG8gaGFkIGxlc3MgdGhhbiAyMCByYXRpbmdzIG9yIGRpZCBub3QgaGF2ZSBjb21wbGV0ZSBkZW1vZ3JhcGhpYyBpbmZvcm1hdGlvbiB3ZXJlIHJlbW92ZWQgZnJvbSB0aGlzIGRhdGEgc2V0LiBEZXRhaWxlZCBkZXNjcmlwdGlvbnMgb2YgdGhlIGRhdGEgZmlsZSBjYW4gYmUgZm91bmQgYXQgdGhlIGVuZCBvZiB0aGlzIGZpbGUuCgpIaWVyIHdpcmQgbnVyIGRpZSBVc2VyLURhdGVpIF91LnVzZXJfIHZlcndlbmRldC4gRGFyYW4ga2FubiBtYW4gZWluZmFjaGUgc3RhdGlzdGlzY2hlIEJlcmVjaG51bmdlbiBkdXJjaGbDvGhyZW4gdW5kIGVpbiBiacOfY2hlbiBpbiBSIHNwaWVsZW4uCgpBbHMgZXJzdGVzIHdlcmRlbiBkaWUgRGF0ZW4gYXVzIGRlciBEYXRlaSBpbiBlaW5lbiBkYXRhZnJhbWUgZWluZ2VsZXNlbiB1bmQsIHVtIHNpZSB6dSB1bnRlcnN1Y2hlbiwgdmVyc2NoaWVkZW5lIEtlbm53ZXJ0ZSB1bmQgRGF0ZW4gYXVmZ2VydWZlbi4KCmBgYHtyfQojIERhdGVpaGFuZGxlIHp1d2Vpc2VuCnUudXNlciA8LSAiL21udC92ZXJhY3J5cHQxL0RhdGEvS3Vyc2UvTGVhcm4gQnkgRXhhbXBsZSAtIFN0YXRpc3RpY3MgYW5kIERhdGEgU2NpZW5jZSBpbiBSLzEwIExpc3RzIGFuZCBEYXRhIEZyYW1lcy9EYXRhZnJhbWVzU291cmNlQ29kZS9tb3ZpZWxlbnMgZGF0YS91LnVzZXIiCiMgSGVhZGVyIGJlbmVubmVuCmhlYWRlciA8LSBjKCJ1c2VySWQiLCJhZ2UiLCJnZW5kZXIiLCJvY2N1cGF0aW9uIiwiemlwQ29kZSIpCiMgRGF0ZW4gaW4gZWluZSBUYWJlbGxlIGVpbmxlc2VuCnVzZXJJbmZvIDwtIHJlYWQudGFibGUodS51c2VyLGhlYWRlciA9IEZBTFNFLCBzZXAgPSJ8IiwgcXVvdGUgPSAiXCInIixjb2wubmFtZXMgPSBoZWFkZXIpCiMgRGllIFRhYmVsbGUgaXN0IGVpbiBkYXRhZnJhbWUKY2xhc3ModXNlckluZm8pCmhlYWQodXNlckluZm8sMTApCiMgQWJydWZlbiB2b24gVGFiZWxsZW56ZWxsZW4KdXNlckluZm9bMjo1LDE6Ml0KdXNlckluZm9bMjo1LGMoMSwzOjQpXQp1c2VySW5mbyRhZ2VbMToxMF0KY2xhc3ModXNlckluZm8kZ2VuZGVyKQpsZW5ndGgobGV2ZWxzKHVzZXJJbmZvJG9jY3VwYXRpb24pKQpsZXZlbHModXNlckluZm8kb2NjdXBhdGlvbikKYGBgCgojIyBHcnVwcGllcnVuZ2VuIHVuZCBSYW5nZXMKClVtIHp1IGJlc3RpbW1lbiwgaW4gd2VsY2hlbiBCZXJlaWNoZW4gZGllIERhdGVuIGxpZWdlbiwgd2VyZGVuIHNpZSBzdW1taWVydCBvZGVyIGdydXBwaWVydC4gVW0gc2llIHNww6R0ZXIgbmFjaCBBbHRlcnNncnVwcGVybiB6dSBjbHVzdGVybiwgd2VyZGVuIEludGVydmFsbGUgYW5nZWxlZ3QuCgpgYGB7cn0KdGFibGUodXNlckluZm8kb2NjdXBhdGlvbikKdGFibGUodXNlckluZm8kZ2VuZGVyKQpyYW5nZSh1c2VySW5mbyRhZ2UpCiMgVGFiZWxsZSBuYWNoIEFsdGVyc2JlcmVpY2hlbiBjbHVzdGVybgpiaW5zIDwtIHNlcSg1LDc1LGJ5PTEwKQppbnRlcnZhbHMgPC0gY3V0KHVzZXJJbmZvJGFnZSxiaW5zLHJpZ2h0PUZBTFNFKQpgYGAKCiMjIEludGVydmFsbGUgdW5kIFZvcmtvbW1lbgoKSGllciB3ZXJkZW4gZGllIGluIGRlbiBJbnRlcnZhbGxlbiBsaWVnZW5kZW4gRGF0ZW4gdW50ZXJzdWNodC4KCmBgYHtyfQojIFZvcmtvbW1lbiBpbiBkZW4gSW50ZXJ2YWxsZW4gaXN0IGhpZXIgbWFsIGF1c2dla2xhbW1lcnQKI2ludGVydmFscwp0YWJsZShpbnRlcnZhbHMpCmNsYXNzKGludGVydmFscykKIyBMZWdlbmRlIGbDvHIgZGllIERhdGVuaW50ZXJ2YWxsZQpuYW1lc0ludCA8LSBwYXN0ZSgiSSIsIGMoMTo3KSwgc2VwPSIiKQpsZWdlbmRJbnQgPC0gZGF0YS5mcmFtZShuYW1lcyh0YWJsZShpbnRlcnZhbHMpKSxuYW1lc0ludCkKbmFtZXMobGVnZW5kSW50KSA8LSBjKCJpbnRlcnZhbCIsIm5hbWUiKQppbnRlcnZhbHMgPC0gY3V0KHVzZXJJbmZvJGFnZSxiaW5zLGxhYmVscz1uYW1lc0ludCxyaWdodD1GQUxTRSkKIyBWb3Jrb21tZW4gZGVzIEFsdGVycyBpbiBkZW4gSW50ZXJ2YWxsZW4KYWdlRnJhbWUgPC0gZGF0YS5mcmFtZShpbnRlcnZhbHMsdXNlckluZm8kYWdlKQphZ2VGcmFtZQpuYW1lcyhhZ2VGcmFtZSkgPC0gYygiSSIsIkFnZSIpCmFnZUZyYW1lCiMgbWFsIHNjaGF1ZW4sIHdhcyBkZXIgVGFibGUtQmVmZWhsIGhpZXIgbWFjaHQKIyBTY2hvbiBlaW5lIHNwYW5uZW5kZSBBdXNnYWJlOiBWb3Jrb21tZW4gZGVzIGVpbnplbG5lbiBBbHRlcnMgaW4gZGVuIEludGVydmFsbGVuCnRhYmxlKGFnZUZyYW1lKQojIFZvcmtvbW1lbiBuYWNoIEdlc2NobGVjaHQKZ2VuZGVyRnJhbWUgPC0gZGF0YS5mcmFtZShpbnRlcnZhbHMsdXNlckluZm8kZ2VuZGVyKQpuYW1lcyhnZW5kZXJGcmFtZSkgPC0gYygiSSIsIkdlbmRlciIpCmdlbmRlckZyYW1lCnRhYmxlKGdlbmRlckZyYW1lKQpgYGAKCiMjIERhdGVuIHBsb3R0ZW4KCkluIFIgZ2lidCBlcyB6aWVtbGljaCB2aWVsZSBNw7ZnbGljaGtlaXRlbiwgRGF0ZW4gZ3JhZmlzY2ggYXVzenVnZWJlbiwgd2llIGljaCBiZWltIEF1c3Byb2JpZXJlbiBnZXNlaGVuIGhhYmUuIEhpZXIga2FubiBtYW4gZWlubWFsIGRpZSBWZXJ0ZWlsdW5nIGluIGRlbiBBbHRlcnNpbnRlcnZhbGxlbiBuYWNoIEdlc2NobGVjaHQgc2VoZW4uIERhbm4gZWlubWFsIGVpbmVuIEJveC1QbG90IGRlciBWZXJ0ZWlsdW5nIGRlcyBBbHRlcnMgZGVyIFRlaWxuZWhtZXIgaW4gZGVuIEFsdGVyc2ludGVydmFsbGVuLCB3YXMgd2FocnNjaGVpbmxpY2ggd2VuaWdlciBzaW5udm9sbCBpc3QuIFVuZCBlaW5lbiBCb3gtUGxvdCBkZXIgVmVydGVpbHVuZyBkZXMgQWx0ZXJzIGbDvHIgRnJhdWVuIHVuZCBNw6RubmVyLiAgCgpgYGB7cn0KIyBMZWdlbmRlIGbDvHIKbGVnZW5kSW50CnBsb3QodGFibGUoZ2VuZGVyRnJhbWUpLCB0eXBlID0iaCIsIG1haW4gPSAiR2VuZGVyIEhpc3RvZ3JhbSIsIHhsYWIgPSAiSW50ZXJ2YWxzIiwgeWxhYiA9ICJNYWxlL0ZlbWFsZSIgKQpoaXN0KHVzZXJJbmZvJGFnZSxicmVha3MgPSBiaW5zKQpid3Bsb3QoQWdlIH4gSSwgZGF0YSA9IGFnZUZyYW1lLHhsYWIgPSAiQWdlIGZyb20uLi50byIsIHlsYWIgPSAiQWdlIixtYWluID0gIkFnZSBvZiBwYXJ0aWNpcGFudHMiKQpnZW5kZXIyRnJhbWUgPC0gZGF0YS5mcmFtZSh1c2VySW5mbyRhZ2UsdXNlckluZm8kZ2VuZGVyKQpuYW1lcyhnZW5kZXIyRnJhbWUpIDwtIGMoIkFnZSIsIkdlbmRlciIpCmJveHBsb3QoQWdlIH4gR2VuZGVyLCBkYXRhID0gZ2VuZGVyMkZyYW1lLHhsYWIgPSAiR2VuZGVyIiwgeWxhYiA9ICJBZ2UiLG1haW4gPSAiR2VuZGVyIG9mIHBhcnRpY2lwYW50cyIpCmBgYAoKIyMgWnVzYW1tZW5mYXNzZW5kZSBTdGF0aXN0aWsgYXVzZ2ViZW4KCkhpZXIgd2VyZGVuIHp1c2FtbWVuZmFzc2VuZGUgc3RhdGlzdGlzY2hlIFdlcnRlIG1pdCBkZXIgYWdncmVnYXRlLUZ1bmt0aW9uIGbDvHIgQmVyZWljaGUgZGVzIGRhdGFmcmFtZXMgYXVzZ2VnZWJlbi4gCgpgYGB7cn0KYWdncmVnYXRlKGFnZSB+IGdlbmRlciwgdXNlckluZm8sIG1lYW4pCmFnZ3JlZ2F0ZShhZ2UgfiBnZW5kZXIgKyBvY2N1cGF0aW9uLCB1c2VySW5mbywgbWVhbikKb2NjdXBhdGlvbkNvdW50cyA8LSBhZ2dyZWdhdGUodXNlcklkIH4gb2NjdXBhdGlvbiwgdXNlckluZm8sIGxlbmd0aCkKaGVhZChvY2N1cGF0aW9uQ291bnRzW29yZGVyKG9jY3VwYXRpb25Db3VudHMkdXNlcklkLCBkZWNyZWFzaW5nID0gVFJVRSksXSwzKQpgYGAKCgoK