TASK1.2 R語言的數(shù)據(jù)類型與數(shù)據(jù)結(jié)構(gòu)
1 預(yù)習(xí)(設(shè)置工作路徑、嘗試讀取數(shù)據(jù))
2 課堂內(nèi)容(匯總函數(shù)、基本數(shù)據(jù)類型、數(shù)據(jù)結(jié)構(gòu))
1 預(yù)習(xí)
1.1設(shè)置工作路徑
我們可以通過
- getwd() 獲取當(dāng)前工作路徑
設(shè)置工作路徑的兩種方法:
1 暫時
- setwd()
- setwd("E:/vvang/Documents/Rstudio/guanghuaBA_workshop/TASK1.2")
2 永久
Tools -> Global option -> General -> Default working directory
1.2 嘗試讀取數(shù)據(jù)
給出了csv、txt、xlsx的數(shù)據(jù),下面分別讀取
1.2.1 讀取csv數(shù)據(jù) (read.csv)
data_csv = read.csv("top250.csv")
發(fā)現(xiàn)報錯“Error in type.convert.default(data[[i]], as.is = as.is[i], dec = dec, : invalid multibyte string at '<b8><a5><c0><bc>'”
考慮可能是編碼問題,先是改為-
data_csv = read.csv("top250.csv", fileEncoding = 'UTF-8')
發(fā)現(xiàn)還有報錯:原因是文檔中包含有中文,文件編碼不匹配造成的,解決方法有在notepad++中將文件轉(zhuǎn)為utf-8編碼,再重新執(zhí)行語句,或者直接修改csv編碼格式為UTF-8。read.csv data_csv = read.csv("top250.csv", fileEncoding = 'GBK')
但是后來發(fā)現(xiàn)改成這樣也可以,可能是因為:GBK包含全部中文字符;UTF-8則包含全世界所有國家需要用到的字符。
具體可參考:
[1] 網(wǎng)絡(luò)編碼GB2312、GBK與UTF-8的區(qū)別 - 百度文庫 (baidu.com)
一些函數(shù)里的arguments這里不再展開,以后直接?打開help
1.2.2 讀取txt數(shù)據(jù) (read.table)
-
data_txt = read.table("top250.txt", header = T, sep = "\t", fileEncoding = "GBK")
保留第一行的變量名,用tab做分隔
1.2.3 讀取xlsx數(shù)據(jù) (read_xlsx)
需要先安裝包:(注意install時要用雙引號括起來,調(diào)用的時候好像不要求)
- install.packages("readxl")
- library(readxl)
-
data_xlsx = read_xlsx("top250.xlsx", col_name = T)
同樣也是用第一行做列名
還可以參考:
[2] R讀取txt、csv、xls和xlsx格式文件_華仔的逆襲的博客-CSDN博客_readtable讀取xlsx
[3] 方匡南的個人網(wǎng)站-關(guān)于R讀取文件的幾個常錯的問題 (kuangnanfang.com)
2 課堂內(nèi)容
2.1 匯總函數(shù)
- class(movie$score):查看數(shù)據(jù)類型,其中dollar用來選取數(shù)據(jù)集中的變量
- head():展示數(shù)據(jù)的前幾行,參數(shù) n = 3L代表只查看前三行
- summary():匯總展示每個變量的結(jié)果(例如總長度、最大最小值、均值等)
- str():緊湊地顯示R對象的內(nèi)部結(jié)構(gòu),讓用戶快速預(yù)覽對象的內(nèi)容和結(jié)構(gòu),比summary()多提供了關(guān)于行(觀察)和列(變量)的信息以及附加信息,如列的名稱、每列的類別以及每列的一些初始觀察
- dim():返回數(shù)據(jù)的維數(shù)
2.2 基本數(shù)據(jù)類型
數(shù)值型
例如class(movie$score)將會得到結(jié)果[1]"numeric"
又或者可以令 a = 2; class(a) 也會得到[1]"numeric"
字符型
但如果令 a = "2"; class(a) 將得到[1] "character"
因子型
(1) factor定性變量:有若干個水平的取值
- movie¥type = factor(movie¥type):將原來的type類型變?yōu)橐蜃有筒⑻娲瓉砟橇?這里因為連打兩個$會變成公式所以用¥暫代)
此時再class(movie$type)就變成了[1] "factor",這個時候type不是無意義的char,而類似于分組中的標(biāo)簽?我們還可以
- table(movie$type):得到不同type下分別有多少個

因子的設(shè)計思想來源于統(tǒng)計學(xué)的名義變量,或稱為分類變量。 分類變量的值本質(zhì)上不是數(shù)字,而是對應(yīng)為分類/分組。 因子分為無序因子和有序因子。
因子的類別稱為level,結(jié)合level,因子在內(nèi)部被編碼為指向level的正整數(shù)序號。


(3) 因子型和字符型數(shù)據(jù)互相轉(zhuǎn)換
- as.factor():將參數(shù)強制轉(zhuǎn)換為factor類型
例如上圖中我們就可以改寫成 x = as.factor(x)
值得注意的是,as.factor()的參數(shù)僅為 x ,levels,exclude,ordered,nmax是factor而非as.factor的參數(shù)。因此,傳遞不使用的參數(shù)會給運行帶來錯誤。
此外與factor()有關(guān)的函數(shù)有:
- is.factor():判斷數(shù)據(jù)是否為factor模式,并返回一個邏輯值TRUE或FALSE
- is.ordered():判斷數(shù)據(jù)是否是有序的,并返回一個邏輯值TRUE或FALSE
- as.ordered():按順序返回參數(shù)x
邏輯型
(1) 判斷TRUE/FALSE
movie¥type[movie¥name == "霸王別姬"] == "愛情"
(這里同樣是用¥代替了$,判斷電影名為霸王別姬的電影,類型是否為愛情片)
輸出 [1] TRUE
(2) 索引 [ 行索引,列索引]
如挑選 score > 9.5 的電影
- movie$score > 9.5:將得到一堆TRUE/FALSE,正確做法應(yīng)該是
- movie[movie$score > 9.5, ]:后面的逗號不能忘,否則報錯“選擇了未定義的列”
- movie[movie$score > 9.5, "nation"]:評分高于9.5的電影來自哪些國家
- movie[movie$score > 9.5, c("nation","type)]:同時篩選兩個或多個列
(3) 邏輯語句加減
如 (1 == 2) + (3 < 4) 將輸出 [1] 1
2.3 數(shù)據(jù)結(jié)構(gòu)
向量
(1) 創(chuàng)建
- c()
- c(1,1,12,3)
- c("a", "b", "c")
- seq(0, 10, by = 2):生成0-10之間以2為間隔的等差數(shù)列
- 1: 10:生成1-10的連續(xù)數(shù)列
(2) 索引
- x = c(1,2,2,4,5); x[5]
- which(x == 4):查看 x 向量中4所在的位置
- which.max(x):返回第一個最大值所在的位置
- which.min(x):返回第一個最小值所在的位置
- which(x==max(x)):返回所有最大值所在的位置
(3) 集合運算
- intersect(x, y):求向量的交集
- union(x, y):求向量的并集
- setdiff(x, y):求向量的差集
(4) 數(shù)值型向量
- range(x):求范圍(最小值,最大值)
- match(x, y):輸出x y向量中相同元素的位置
-
cut(x, breaks = , labels = ):將向量 x 按照breaks給出的區(qū)間劃分/離散化cut
- sort(x):輸出向量x排序后的結(jié)果,不改變x原來的排序,逆序decreasing = T
- order(x):輸出向量x中每個元素在順序或逆序排列時對應(yīng)的位置
- x[order(x)] == sort(x)
(5) 字符串向量
- nchar():提取字符串的長度(英文中的空格也算)
- length():元素的個數(shù)
- nchar("明天是晴天")
輸出:5 - length("明天是晴天")
輸出:1
因為只有一個元素/一個字符串
- substr(“R語言學(xué)習(xí)筆記”, 1, 3):提取子字符串,輸出R語言
- strsplit(x, split = ' '):將字符串按照某種分割形式進行劃分,需要設(shè)定分隔符
- paste(...., collapse = , sep = " " ):將參數(shù)轉(zhuǎn)換為字符串并連接它們
其中,...表示對象,可以有多個,中間用逗號隔開,
sep:表示參數(shù)之間的分隔符,默認(rèn)為空格
collapse:表示如果不指定值,那么函數(shù)paste的返回值是...的對象之間通過sep指定的分隔符連接后得到的一個字符型向量;如果為其制定了特定的值,那么自變量連接后的字符型向量會再被連接成一個字符串,之間通過collapse的值分隔
grep():負責(zé)搜索給定字符串對象中特定表達式,并返回其位置索引。grepl()函數(shù)與之類似,但其后面的”l”則意味著返回的將是邏輯值
chartr(old, new, x):字母替換,要求新舊長度一致
sub(old, new, x):替換第一個出現(xiàn)的字符串
gsub(old, new, x):替換全部old參數(shù)
a = 'I love you, do you love me?'
- (chartr = ('you', 'she', a))
輸出'I lhve she, dh she lhve me?' - (sub = ('you', 'she', a))
輸出'I love she, do you love me?' - (gsub('you', 'she', a))
輸出'I love she, do she love me?’
- toupper(x):全部替換為大寫
- tolower(x):全部替換為小寫
矩陣
(1) 創(chuàng)建
- mat_a = matrix(1:12, nrow = 3, ncol = 4):創(chuàng)建一個3x4的矩陣
1:12沿列填充,可以用bycol = T改為沿行填充 - dig_0 = diag(1 : 4)
- dig_1 = diag(rep(1, 4)):生成一個對角全是1的矩陣
- rep(x, time = , length.out = , each = ,)
- x代表你要進行復(fù)制的對象,可以是一個向量也可以是一個因子
- times代表復(fù)制的次數(shù),對象是整個向量
- length.out代表最終輸出向量的長度
- each代表對向量中的每個元素進行復(fù)制的次數(shù)
- rep(x, time = , length.out = , each = ,)
(2) 基本的矩陣操作
- dim(mat_a):查看矩陣的維度
輸出 3 4 - nrow(mat_a):提取矩陣的行數(shù)
輸出 3
-ncol(mat_a):提取矩陣的列數(shù)
輸出 4 - mat_a[1:2, 2:3]:提取12行(1,2行),23列(2,3列)
給行列命名: - colnames(mat_a) : paste("x_", 1:4)
- rownames(mat_a):1:3
調(diào)用行列名: - colnames(mat_a)
- rownames(mat_a)
將多個矩陣合并 - rbind(A, B):在A下增加行,要求列數(shù)一致
- cbind(A, B):在A右增加列,要求行數(shù)一致
(3) 矩陣的數(shù)學(xué)操作
- A + B:要求A、B大小一樣,矩陣元素一一對應(yīng)相加
- A - B:同上
- A * B:同上,點乘
- A %*% B:矩陣的乘法
- solve(mat_a):求矩陣的逆
- eigen(mat_a):求矩陣的特征值
數(shù)組

(1) 創(chuàng)建
-
array(data = NA, dim = length(data), dimnames = NULL)
- data:向量,數(shù)組元素
- dim:數(shù)組的維度,默認(rèn)一維
- dimnames:維度的名稱,必須是個列表,默認(rèn)情況下不設(shè)置名稱
-
result = array(1:18, dim = c(3,3,2), dimnames = list(c("r1","r2","r3"),c("c1","c2","c3"),c("h1","h2")))
- 創(chuàng)建兩個不同長度的向量
- vector1 = c(5,9,3)
- vector2 = c(10,11,12,13,14,15)
- result = array(c(vector1, vector2), dim = c(3, 3, 2))將得到兩個一樣的(3, 3)矩陣
result[1, 2, 2]:獲取單個元素
result[1, , ]:獲取第一維度的數(shù)據(jù)
(2) 操作數(shù)組元素
- matrix1 = result[, , 1]:獲取數(shù)組中第1水平的矩陣
- matrix2 = result[, , 2]:獲取數(shù)組中第2水平的矩陣
- add = matrix1 + matrix2 :矩陣相加
數(shù)據(jù)框
(1) 創(chuàng)建
讀入一個txt,csv等格式的數(shù)據(jù),即自成一個數(shù)據(jù)框
- movie = read.csv("top250.csv", fileEncoding = "gbk", stringsAsFactors = F)
- class(movie):輸出"data.frame"
或自己創(chuàng)建
- director <- c("陳凱歌", "宮崎駿", "李廷香","詹姆斯·卡梅隆", "劉鎮(zhèn)偉", "周星馳", "李安", "姜文", "張藝謀", "吳宇森","巖井俊二", "王家衛(wèi)", "陳可辛" )
- birthyear <- c(1952,1941,1964,1954,1952,1962,1954,1963,1950,1946,1963,1958,1962)
- gender <- c("男", "男", "女", "男", "男", "男", "男", "男", "男", "男", "男", "男", "男")
- directors <- data.frame(director, birthyear, gender); head(directors)
不能用數(shù)字作為變量開頭,如果想用數(shù)字開頭怎么辦呢?
真是把所有可能出現(xiàn)的錯誤都踩了一遍
(2) 變形--長寬表互換
需要install.packages("reshape2")
1 寬表變長表
- mLong = melt(mWide, id.vars = c("Name", "Type"), variable.name = "Year")
melt 是溶解/分解的意思, 即拆分?jǐn)?shù)據(jù)。
reshape/reshape2 的 melt 函數(shù)是個 S3 通用函數(shù),它會根據(jù)數(shù)據(jù)類型(數(shù)據(jù)框,數(shù)組或列表)選擇 melt.data.frame, melt.array 或 melt.list 函數(shù)進行實際操作。
-
melt(data, id.vars, measure.vars, variable.name = "variable", ..., na.rm = FALSE, value.name = "value")
- data:所選的數(shù)據(jù)
- id.vars:標(biāo)識變量,不想改變的數(shù)據(jù)列
- measure.vars:度量變量,需要melt的數(shù)據(jù),通常如果只制定了id.vars剩下的就是measure.vars,反之同理
- variable.name:melt之后,新列變量的取名
- value.name:melt之后,新列變量的對應(yīng)值的取名
[6] melt()函數(shù)的作用是什么? - R語言論壇 - 經(jīng)管之家(原人大經(jīng)濟論壇) (pinggu.org)
插播一個輸出markdown格式的dataframe的方式
- install.packages("knitr")
- library(knitr)
- kable(mWide, format = "markdown")
2 長表變寬表
- dcast(mLong, Name + Type ~Year)
-
dcast(data, formula, fun.aggregate)
- data:所選的數(shù)據(jù)
- formula:描述了想要的結(jié)果,其接受的公式形如:rowvar1 + rowvar2 + ... ~ colvar1 + colvar2 + ...;在這一公式中,rowvar1 + rowvar2 + ...定義了要劃掉的變量集合,以確定各行的內(nèi)容,而colvar1 + colvar2 + ...則定義了要劃掉的、確定各列內(nèi)容的變量集合。簡單來說就是:
- ~左邊是保持不變的列名
- ~右邊是需要擴展的列名
- 省略的(value.name = "value")是需要填充的數(shù)據(jù)
- fun.aggregate是(可選的)數(shù)據(jù)整合函數(shù),比如求均值等等
(3) dplyr
列表
(1) 創(chuàng)建
(2) 基本操作
(3) 列表中的**ply函數(shù)


