目录
(8)应用于数据框的函数:lapply()和sapply()
- > d<-data.frame(list(kids=c("Jack","Jill"),ages=c(12,10)))
- > d
- kids ages
- 1 Jack 12
- 2 Jill 10
- > d$ages
- [1] 12 10
•通过组件的索引值或组件名来访问数据框中的组件
- > d[[1]]
- [1] "Jack" "Jill"
- > d$kids
- [1] "Jack" "Jill"
•也可以通过类似矩阵的方式访问
- > d[,1]
- [1] "Jack" "Jill"
用str()查看d的内部结构,可以看出d具有矩阵的特征
- > str(d)
- 'data.frame': 2 obs. of 2 variables:
- $ kids: chr "Jack" "Jill"
- $ ages: num 12 10
•使用[ ]运算符提取特定行和列
- # 创建一个示例数据框
- df <- data.frame(
- name = c("Alice", "Bob", "Charlie"),
- age = c(25, 30, 35),
- gender = c("female", "male", "male")
- )
-
- # 提取第 2 行和第 3 列到第 4 列的子数据框
- subset_df <- df[2, 3:4]
-
- # 输出子数据框
- print(subset_df)
- # 输出:
- # gender
- # 2 male
-
- #保留提取子数据框时的空行或空列
- > df <- data.frame(
- + name = c("Alice", "Bob", "Charlie"),
- + age = c(25, NA, 35),
- + gender = c("female", "", "male")
- + )
- > subset_df <- df[, , drop = FALSE]
- >
- > print(subset_df)
- name age gender
- 1 Alice 25 female
- 2 Bob NA
- 3 Charlie 35 male
•使用subset()函数提取符合条件的子数据框
- # 创建一个示例数据框
- df <- data.frame(
- name = c("Alice", "Bob", "Charlie"),
- age = c(25, 30, 35),
- gender = c("female", "male", "male")
- )
-
- # 提取年龄大于等于 30 的子数据框
- subset_df <- subset(df, age >= 30)
-
- # 输出子数据框
- print(subset_df)
- # 输出:
- # name age gender
- # 2 Bob 30 male
- # 3 Charlie 35 male
-
- # 创建一个示例数据框
- df <- data.frame(
- name = c("Alice", "Bob", "Charlie"),
- age = c(25, NA, 35),
- gender = c("female", "", "male")
- )
-
- # 提取子数据框并保持空行和空列
- subset_df <- subset(df, , drop = FALSE)
-
- # 输出子数据框
- print(subset_df)
-
- > subset_df
- name age gender
- 1 Alice 25 female
- 2 Bob NA
- 3 Charlie 35 male
•使用逻辑运算符和比较运算符提取符合条件的子数据框
- # 创建一个示例数据框
- df <- data.frame(
- name = c("Alice", "Bob", "Charlie"),
- age = c(25, 30, 35),
- gender = c("female", "male", "male")
- )
-
- # 提取年龄大于等于 30 且性别为男性的子数据框
- #保留所有的列,筛选行
- subset_df <- df[df$age >= 30 & df$gender == "male", ]
-
- # 输出子数据框
- print(subset_df)
- # 输出:
- # name age gender
- # 2 Bob 30 male
- # 3 Charlie 35 male
- > x<-c(2,NA,4)
- > mean(x)
- [1] NA
- > mean(x,na.rm = TRUE)
- [1] 3
-
-
- #在subset()函数中,不用自己设定na.rm=TRUE
- df[df$age >= 30 & df$gender == "male", ]
- #上面的语句也可以写为
- subset(df,age>=30 & gender=="male")
- #可以不用写为
- subset(df,df$age>=30 & df$gender=="male")
-
- #用于检测数据框或矩阵中是否存在缺失值,并返回一个逻辑向量,指示每个观测是否完整(不包含缺失值)
- df <- data.frame(
- name = c("Alice", "Bob", NA, "Dave"),
- age = c(25, 30, NA, 40),
- gender = c("female", "male", NA, "male")
- )
-
- # 使用 complete.cases() 检测完整观测
- complete_obs <- complete.cases(df)
-
- # 输出检测结果
- print(complete_obs)
-
- [1] TRUE TRUE FALSE TRUE
-
- #complete.cases()也可以去掉空缺值
- d<-data.frame(list(kids=c("Jack",NA,"Jillian","John"),ages=c(12,10,NA,13)))
- > d
- kids ages
- 1 Jack 12
- 2 <NA> 10
- 3 Jillian NA
- 4 John 13
- > complete.cases(d)
- [1] TRUE FALSE FALSE TRUE
- > d2<-d[complete.cases(d),]
- > d2
- kids ages
- 1 Jack 12
- 4 John 13
- > d2
- kids ages
- 1 Jack 12
- 4 John 13
- #rbind用于添加新行
- > rbind(d2,list("halo",19))
- kids ages
- 1 Jack 12
- 4 John 13
- 11 halo 19
-
- #cbind() 函数用于按列合并两个或多个对象(如向量、矩阵、数据框)
- #合并两个向量
- x <- c(1, 2, 3)
- y <- c("A", "B", "C")
-
- result <- cbind(x, y)
-
- print(result)
- x y
- [1,] "1" "A"
- [2,] "2" "B"
- [3,] "3" "C"
-
- #合并两个矩阵
- x <- matrix(1:6, nrow = 2)
- y <- matrix(7:12, nrow = 2)
-
- result <- cbind(x, y)
-
- print(result)
- [,1] [,2] [,3] [,4] [,5] [,6]
- [1,] 1 3 5 7 9 11
- [2,] 2 4 6 8 10 12
-
- #合并数据框
- df1 <- data.frame(x = c(1, 2, 3), y = c("A", "B", "C"))
- df2 <- data.frame(z = c(TRUE, FALSE, TRUE), w = c(0.1, 0.2, 0.3))
-
- result <- cbind(df1, df2)
-
- print(result)
- x y z w
- 1 1 A TRUE 0.1
- 2 2 B FALSE 0.2
- 3 3 C TRUE 0.3
-
- #可以给原来的数据框添加result中的元素
- > df1$number<-result$x
- > df1
- x y number
- 1 1 A 1
- 2 2 B 2
- 3 3 C 3
apply(X, MARGIN, FUN, ...)
X:要应用函数的矩阵或数据框。MARGIN:一个整数向量,指定应用函数的维度。MARGIN = 1表示按行应用函数,MARGIN = 2表示按列应用函数。FUN:要应用的函数。...:传递给函数FUN的其他参数。
- #回顾之前apply在矩阵中的应用
- # 创建一个矩阵
- mat <- matrix(1:9, nrow = 3)
-
- # 使用 apply() 计算每行的和
- row_sums <- apply(mat, 1, sum)
-
- print(row_sums)
- [1] 12 15 18
-
-
- # 创建一个数据框
- df <- data.frame(x = c(1, 2, 3), y = c(4, 5, 6), z = c(7, 8, 9))
-
- # 使用 apply() 计算每列的均值
- col_means <- apply(df, 2, mean)
-
- print(col_means)
- #输出
- x y z
- 2 5 8
-
-
- #自定义函数
- mat <- matrix(1:9, nrow = 3)
-
- # 自定义函数:计算平方根
- sqrt_sum <- function(x) {
- sqrt(sum(x))
- }
-
- # 使用 apply() 应用自定义函数
- result <- apply(mat, 2, sqrt_sum)
-
- print(result)
- [1] 2.449490 3.872983 4.898979
- #按照共同的列合并数据框
- # 创建两个数据框
- df1 <- data.frame(id = c(1, 2, 3), name = c("Alice", "Bob", "Charlie"))
- df2 <- data.frame(id = c(2, 3, 4), age = c(25, 30, 35))
-
- # 按照共同的列 "id" 合并数据框
- result <- merge(df1, df2, by = "id")
-
- print(result)
- id name age
- 1 2 Bob 25
- 2 3 Charlie 30
-
- #按照不同的列名合并数据框
- # 创建两个数据框
- df1 <- data.frame(id = c(1, 2, 3), name = c("Alice", "Bob", "Charlie"))
- df2 <- data.frame(emp_id = c(2, 3, 4), age = c(25, 30, 35))
-
- # 按照不同的列 "id" 和 "emp_id" 合并数据框
- result <- merge(df1, df2, by.x = "id", by.y = "emp_id")
-
- print(result)
- id name age
- 1 2 Bob 25
- 2 3 Charlie 30
-
- #根据所有的列合并数据框
- # 创建两个数据框
- df1 <- data.frame(id = c(1, 2, 3), name = c("Alice", "Bob", "Charlie"))
- df2 <- data.frame(id = c(2, 3, 4), age = c(25, 30, 35))
-
- # 根据所有的列合并数据框
- result <- merge(df1, df2, all = TRUE)
-
- print(result)
- id name age
- 1 1 Alice NA
- 2 2 Bob 25
- 3 3 Charlie 30
- 4 4 <NA> 35
- > d<-data.frame(list(kids=c("Jack","Jill"),ages=c(12,10)))
- > d
- kids ages
- 1 Jack 12
- 2 Jill 10
-
- > d1<-data.frame(list(kids=c("Jack","Jill","Jillian","John"),states=c("CA","MA","MA","HI")))
- > d1
- kids states
- 1 Jack CA
- 2 Jill MA
- 3 Jillian MA
- 4 John HI
-
-
- > d2a<-rbind(d,list("Jill",15))
- > d2a
- kids ages
- 1 Jack 12
- 2 Jill 10
- 3 Jill 15
-
- > merge(d2a,d1)
- kids ages states
- 1 Jack 12 CA
- 2 Jill 10 MA
- 3 Jill 15 MA
- #由上图可知,d2a有两个Jill,但是只有一个Jill住在MA,另外一个不知道,所以匹配的时候出现错误
- #所以匹配向量的时候也要谨慎
lapply():对列表(list)或向量(vector)的每个元素应用一个函数,并返回一个新的列表。
lapply(X, FUN, ...)
X:要操作的列表或向量。FUN:要应用到每个元素上的函数。...:其他参数,传递给FUN函数。
- #统计每个数据框的行数
-
- my_list <- list(df1 = data.frame(x = 1:3, y = 4:6),
- df2 = data.frame(a = 1:5, b = 6:10))
-
- # 统计每个数据框的行数
- result <- lapply(my_list, function(df) nrow(df))
-
- print(result)
- $df1
- [1] 3
-
- $df2
- [1] 5
-
-
- > d
- kids ages
- 1 Jack 12
- 2 Jill 10
- > d1<-lapply(d, sort)
- > d1
- #d1是由两个向量构成的列表,这两个向量是排序后的kids和ages
- $kids
- [1] "Jack" "Jill"
-
- $ages
- [1] 10 12
-
- #强行转化为数据框,但是这样做会丢失名字和年龄的对应关系,所以这样的转化没有意义,不用做
- > as.data.frame(d1)
- kids ages
- 1 Jack 10
- 2 Jill 12
-
sapply():对数据框或列表等对象的每一列(或元素)进行逐一的操作并返回结果
sapply(X, FUN, ...)
X:要操作的数据框或列表等对象。FUN:要应用到每一列(或元素)上的函数。...:其他参数,传递给FUN函数。
- # 创建一个数据框
- df <- data.frame(x = c(1, 2, 3), y = c(4, 5, 6))
-
- # 计算每列的均值
- result <- sapply(df, mean)
-
- print(result)
- x y
- 2 5
-
- # 创建一个数据框
- df <- data.frame(x = c("a", "b", "c"), y = c("d", "e", "f"))
-
- # 合并每列的字符向量
- result <- sapply(df, paste, collapse = ", ")
- #collapse:指定向量的连接符
-
- print(result)
- x y
- "a, b, c" "d, e, f"