R語言數據結構與數據處理基礎內容

  • 5.1向量
  • 5.2矩陣與數組
  • 5.3數據框
  • 5.4因子
  • 5.5列表

5.1向量

# 數據結構與數據處理

# 5.1向量
# seq創建向量
seq(from = 1, to = 10, by = 1) 
# rep創建向量
x <- rep(3, 3)
rep(1:3, 2)      #已向量1:3舉例,可換做任意向量,下文不在贅述
rep(1:3, each = 2)
#使用索引訪問向量
my_vex = 1:3
for(i in 1:length(my_vex)){
  print(my_vex[i])
}
my_vex[10] #NA
my_vex[10] = 1; length(my_vex) #長度發生改變
my_vex[c(-1, -2)] #不查看1,2索引的值
#練習:刪除1:10向量的後5個數
my_vex = seq(1, 10, 1)
my_vex <- my_vex[-(length(my_vex) - 5 + 1) : -length(my_vex)]
#使用邏輯型訪問索引
my_vex[c(T,F)] #注意:向量不夠長會循環補齊變為TFTF...所以結果為1 3 5
my_vex[c(T,T,F,F,F)]
#append(my_vex, vec_you_want, after = )函數添加索引
append(my_vex, 1:3, after = 1) #在第一個數字後添加123
#循環補齊,向量向加減等操作如果不夠長,便會循環補齊,像上面所示
#向量的比較
c(1, 2, 3) == c(1, 2, 3)  # > < >= <= != == 都會逐個元素比較
identical(c(1, 2, 3), c(1, 2, 3) #整體比較
          
identical(1.1 - 0.2, 0.9)#浮點數比較不能用identical,因為有精度誤差
all.equal(1.1 - 0.2, 0.9)#all.equal相當於近似計算相等
          
v1 <- c(1: 5)
any(v1 > 3? #any 向量中是否有值大於3
all(v1 > 3) #all 向量中是?袢看笥?3

#按條件提取元素 例(選出平方大於5的元素)
# 這只是一種方法,當然也可以if函數+ for遍歷
v1 <- -3:3
v1 * v1
v1 * v1 > 5
v2 <- v1[v1*v1 > 5]; v2

5.2矩陣與數組

#5.2矩陣與數組
#創建矩陣 , 默認列優先
#1.
matrix(1:12, nrow = 3, ncol = 4, byrow = F,
   dimnames = list(c("fir", "sec", "thi"), c("fir", "sec", "thi", "fou")))
#2.
y <- 1:12
dim(y) <- c(3, 4)
print(y)
#對角矩陣的創建
x <- 1: 3; diag(x)
x <- rep(1: 3); diag(x)
#矩陣的拼接 
mat1 <- rbind(A = 1:3, B = 4:6); mat1 #行拼接
mat2 <- cbind(mat1, c(7, 8), c(9, 10)); mat2 #列拼接
#線性代數的運算
#1 矩陣乘法 %*%
mat1 <- matrix(c(1: 6), nrow = 3); mat1
mat2 <- matrix(c(11:16), nrow = 2); mat2 
mat1 %*% mat2
#2 矩陣轉置
mat3 <- t(mat1); mat3
#3. 矩陣?哪?
mat3 <- 1:4
dim(mat3) <- c(2, 2)
mat3 <- solve(mat3); mat3
#4. 矩陣的行列式值
det(mat3)
#5. 特徵值分解eigen()
mat <- matrix(1: 9, nrow = 3)
eigen(mat)
#使用矩陣索引,讀者可隨便玩玩,R語言的訪問很寬泛
mat1
mat1[,1]
mat1[1,];
mat1[2,2]
mat2
mat2[1,2:3]

# apply函數族
mat <- matrix(1:9, nrow = 3)
apply(mat, 1, sum) #1是按行 2是按列, 最後面的參數是個函數,可以自己寫
apply(mat, 2, sum)

f <- function(x){
return (x - 1)
}
mat <- matrix(1:6, 3); mat
f(mat)#觀察一下直接調用和下面的apply函數調用的區別
apply(mat, 1, f)
#多維數組
dim1 = c("Tom","Bob")
dim2 = c("math","chemis","phy")         
dim3 = c("semes_one", "semes_two")         
array(1:12, c(2, 3, 2), dimnames = list(dim1, dim2, dim3))

5.3數據框

#5.3數據框
#1. 數據框的創建
names <- c("Tom", "Bob","Jerry")
ages <- c(19,18,20)
df <- data.frame(names, ages, stringsAsFactors = F); df #stringsAsFactors = F 是為了防止自動轉換為因子,具體見下文
#數據框的合併
#注意:rbind cbind 都不會改變原來的df,只有重新賦值後才可以。
rbind(df, list("Rose", 20)) #添加行,每一行是list,不是vec
cbind(df, weight = c(70, 73, 60))#添加列,每一列是vec,不是list
str(rbind(df, list("Fan","20")))
#merge()函數合併數據框
df1 <- data.frame( name = c("Tom", "Bob","Jerry"), age = c(19,18,20)); df1
df2 <- data.frame( name = c("Bob", "Tom","Jerry"), score = c(90,85,88)); df2
merge(df1, df2, by = "name")
#訪問數據框中的元素
df1[2,] #訪問第二行
df1[,1] #訪問第一列
df1['name'] #訪問name列
df1$age #訪問age列 $符號可以理解為提取後面的列
#給數據框添加行名
row.names(df1) <- c("stu1", "stu2", "stu3"); df1
#使用sql語句查詢數據框
install.packages("sqldf")
library(sqldf)
sqldf("select * from df1 where age > 18")

5.4因子

#5.4因子
data = c("East", "West", "North", "South", "East", "East", "West")
data_fac <- factor(data); data_fac
levels(data_fac) 
as.numeric(data_fac) #以數值類型顯示因子,數值是上面levels的索引
data_fac[length(data_fac) + 1] = "East"; data_fac #可以添加已存在的因子水平
data_fac[length(data_fac) + 1] = "center"; data_fac #添加不存在的因子水平會產生NA
summary(data_fac)#因子總結函數 summary()

5.5列表

#5.5列表
#列表中可以包含多種數據類型
my_list <- list("it's a string of a list", num_vec1 = c(1, 2, 1), 
                num_vec2 = c(3, 4, 5), df = data.frame(name = c("Tom", "Bob"), age = c(19, 18)),
                fun = function(v1, v2){return (v1 + v2)}); my_list
#可以通過索引號或者$符號訪問列表中的元素
my_list[[1]] #訪問第一個元素.  注意:這裏是雙中括號
my_list$num_vec1 #訪問num_vec1元素

#5.6數據的導入與導出
df <- read.table("C:\\Users\\21136\\OneDrive\\Desktop\\data.txt", header = T) #導入txt文件 要在當前工作目錄下 可以用getwd()查看工作目錄。 sep是分隔符
#除了read.table 還有read.csv read.csv2等函數,讀者可自行查看幫助文檔
write.table(df, file = "C:\\Users\\21136\\OneDrive\\Desktop\\data.txt", sep = "\t") #導出txt文件, 會覆蓋掉原來的文件

#5.7數據清洗
#排序
v <- c(3, 1, 4, 2)
sort(v) #升序排序
sort(v, decreasing = T) #降序排序
order(v) #返回排序後元素的索引
order(-v) #降序排序後元素的索引
v[order(v)] #等同於sort(v)

df <- data.frame(a = c(5, 2, 2, 2), b = c(2, 5, 4, 9), c = c(75, 435, 43, 735))
df[order(df$a, -df$b), ] #先按a升序,再按b降序排序

#離羣點
x <- c(1:10, 20, -8)
boxplot.stats(x)$out #提取離羣點
#缺失值NA的處理
x <- c(1, 2, NA, 4, NA, 5)
mean(x) #結果為NA
mean(x, na.rm = T) #去掉NA後計算均值