如何提取data frame列表中的列名?及distance matrix行最小距离对应列名
帮你搞定两个问题:提取DataFrame列表列名 + 距离矩阵最小距离对应列名
一、提取DataFrame列表里的列名
如果你的列表全是DataFrame,用lapply()就能轻松批量提取每个DataFrame的列名,举个实际例子:
先构造一个示例DataFrame列表:
# 造两个测试用的DataFrame df1 <- data.frame(用户ID = 1:3, 订单金额 = 100:102) df2 <- data.frame(商品名 = c("苹果", "香蕉", "橙子"), 库存 = 50:52, 单价 = 5:7) df_list <- list(df1, df2)
然后一行代码提取所有列名:
# 提取列表中每个DataFrame的列名 各表列名 <- lapply(df_list, colnames)
运行后你会得到一个列表,每个元素对应原列表中DataFrame的列名。要是想把所有列名合并成一个向量,加个unlist()就行:
所有列名 <- unlist(各表列名)
二、提取距离矩阵每行最小距离对应的列名
针对你已经生成的距离矩阵列表,咱们可以写个小函数批量处理,既保留最小距离值,又拿到对应的列名。先补全你的示例代码,顺便给矩阵加上列名(没有列名的话结果会是列索引,不太直观):
# 构造你提到的矩阵列表 A <- matrix(c(5, 4, 2, 1, 5, 7), nrow=3, ncol=3, byrow = TRUE) B <- matrix(c(2, 5, 10, 9, 8, 7), nrow=3, ncol=3, byrow = TRUE) # 给矩阵加列名,方便后续对应 colnames(A) <- c("组1", "组2", "组3") colnames(B) <- c("组1", "组2", "组3") list.matrix <- list(A, B)
接下来写一个自定义函数,专门处理单个矩阵:
# 自定义函数:输入单个矩阵,返回每行的最小距离和对应列名 获取最小距离信息 <- function(mat) { # 提取每行的最小距离(你已经会这步啦) 最小距离值 <- apply(mat, 1, min) # 提取对应列名:找到每行最小值的位置,再匹配列名 对应列名 <- apply(mat, 1, function(行数据) { colnames(mat)[which.min(行数据)] }) # 把结果整成DataFrame,看着更清楚 data.frame(最小距离 = 最小距离值, 对应分组 = 对应列名) }
然后批量处理整个矩阵列表:
# 批量处理所有矩阵 结果列表 <- lapply(list.matrix, 获取最小距离信息)
现在看结果,第一个矩阵的输出是:
结果列表[[1]] # 最小距离 对应分组 # 1 2 组3 # 2 1 组1 # 3 5 组1
第二个矩阵的输出是:
结果列表[[2]] # 最小距离 对应分组 # 1 2 组1 # 2 7 组3 # 3 7 组3
额外小提示:
如果你的矩阵没有设置列名,which.min()会返回列的序号(比如1、2、3),记得先给每个矩阵用colnames(你的矩阵) <- c("名称1", "名称2")设置好。另外,如果某一行有多个相同的最小值,which.min()只会返回第一个出现的列名,要是想把所有符合的列名都列出来,可以把函数里的which.min()改成which(行数据 == min(行数据)),再用paste()合并:
# 处理多最小值情况的函数 获取多最小距离列名 <- function(mat) { 最小距离值 <- apply(mat, 1, min) 对应列名 <- apply(mat, 1, function(行数据) { 匹配列位置 <- which(行数据 == min(行数据)) paste(colnames(mat)[匹配列位置], collapse = ", ") }) data.frame(最小距离 = 最小距离值, 对应分组 = 对应列名) }
这样遇到有多个最小值的行,就会把所有对应列名都列出来啦~
内容的提问来源于stack exchange,提问作者P. Bear
相关产品推荐
相关产品推荐

