假设我有一个简单的6x6矩阵,如下所示:

x <- matrix(1:36, nrow = 6, dimnames = list(c("AUS1","AUS2","AUS3", "AUT1", "AUT2", "AUT3"), c("AUS1","AUS2","AUS3", "AUT1", "AUT2", "AUT3")))

     AUS1 AUS2 AUS3 AUT1 AUT2 AUT3
AUS1    1    7   13   19   25   31
AUS2    2    8   14   20   26   32
AUS3    3    9   15   21   27   33
AUT1    4   10   16   22   28   34
AUT2    5   11   17   23   29   35
AUT3    6   12   18   24   30   36

字母代表一个国家(澳大利亚为澳大利亚),后面的数字代表一个部门.现在,我想对每一列求和,但条件是只取来自不同国家的行的值.例如,第一列(AUS1)的总和应仅包含行AUT1、AUT2和AUT3的值.AUS2和AUS3列也是如此.

因为我的表比这个大得多,所以我不能简单地 Select 单独的行.

我在考虑一个函数,它将部分列名和部分行名进行匹配.如果它们包含相同的三个字母,则该值不包含在总和中.

推荐答案

下面是另一种基本R方式:

matched_sum <- function(dfr){
    matched_col <- function(col_id) {
        col_pattern <- gsub("[0-9]", "", colnames(dfr[col_id]))
        dfr[grepl(col_pattern, rownames(x)),col_id] <- NA
        return(dfr[col_id])
    }
    new_col <- lapply(1:ncol(dfr), matched_col)
    new_dfr <- do.call(cbind.data.frame, new_col)
    colSums(new_dfr, na.rm = TRUE)
}

# Your data frame. You can use as.data.frame(x) in case x is not a data frame 
x
     AUS1 AUS2 AUS3 AUT1 AUT2 AUT3
AUS1    1    7   13   19   25   31
AUS2    2    8   14   20   26   32
AUS3    3    9   15   21   27   33
AUT1    4   10   16   22   28   34
AUT2    5   11   17   23   29   35
AUT3    6   12   18   24   30   36

# Apply the function to x
matched_sum(x)

AUS1 AUS2 AUS3 AUT1 AUT2 AUT3 
  15   33   51   60   78   96 

函数的作用

  1. col_pattern <- gsub("[0-9]", "", colnames(dfr[col_id]))在每个列名中查找模式.模式是数字以外的任何字符串.例如:"AUS1"中的模式是"AUS".
  2. dfr[grepl(col_pattern, rownames(x)),col_id] <- NA将NA分配给列中具有在第一步中找到的模式的任何行.例如,此步骤后的第一列将变为:
    AUS1
AUS1   NA
AUS2   NA
AUS3   NA
AUT1    4
AUT2    5
AUT3    6
  1. lapply(1:ncol(dfr), matched_col)将第一步和第二步应用于数据框中的每一列.
  2. do.call(cbind.data.frame, new_col)将所有列(所选行中已包含NA)绑定到数据帧.例如,如果您提供的输入为x,则在此步骤之后,它将变为:
     AUS1 AUS2 AUS3 AUT1 AUT2 AUT3
AUS1   NA   NA   NA   19   25   31
AUS2   NA   NA   NA   20   26   32
AUS3   NA   NA   NA   21   27   33
AUT1    4   10   16   NA   NA   NA
AUT2    5   11   17   NA   NA   NA
AUT3    6   12   18   NA   NA   NA
  1. colSums(new_dfr, na.rm = TRUE)对第4步中创建的数据帧中每列中的所有非NA值求和.

如果要保留数据的矩阵 struct ,可以使用以下方法:

matched_sum_mat <- function(mat){
    matched_col <- function(col_id) {
        col_pattern <- gsub("[0-9]", "", dimnames(mat)[[2]][col_id])
        mat[grepl(col_pattern, dimnames(mat)[[1]]),col_id] <- NA
        return(mat[,col_id])
    }
    new_col <- lapply(1:ncol(mat), matched_col)
    new_mat <- do.call(cbind, new_col)
    colnames(new_mat) <- colnames(mat)
    colSums(new_mat, na.rm = TRUE)
}

# Apply to x as a matrix

matched_sum_mat(x)

AUS1 AUS2 AUS3 AUT1 AUT2 AUT3 
  15   33   51   60   78   96 

更新

如果您希望列名和行名之间的值为exact match,例如列名中的"AUS1"和行名中的"AUS1"(而不是"AUS")之间的值,则可以通过以下几种方式获得该值:

# Option 1
matched_name_location <- lapply(
   colnames(x), 
   function(a_col_name) rownames(x) %in% a_col_name) |> 
   unlist() |> 
   which()
x[matched_name_location] <- NA

# The result
     AUS1 AUS2 AUS3 AUT1 AUT2 AUT3
AUS1   NA    7   13   19   25   31
AUS2    2   NA   14   20   26   32
AUS3    3    9   NA   21   27   33
AUT1    4   10   16   NA   28   34
AUT2    5   11   17   23   NA   35
AUT3    6   12   18   24   30   NA

另一种 Select 是使用==而不是%in%:

# Option 2
matched_name_location <- lapply(
   colnames(x), 
   function(a_col_name) rownames(x) == a_col_name) |> 
   unlist() |> 
   which()
x[matched_name_location] <- NA

另一种 Select 是使用grepl.

# Option 3
matched_name_location <- lapply(
   colnames(x), 
   function(a_col_name) grepl(a_col_name, rownames(x))) |> 
   unlist() |> 
   which()
x[matched_name_location] <- NA

最后一个用于查找模式within a字符串.例如,它grepl("AUS1", "AUS10")返回TRUE,而"AUS1" %in% "AUS10""AUS1" == "AUS10"中的每一个都返回FALSE.

R相关问答推荐

替换字符的所有实例,但仅限于匹配字符串中

如何判断R中一列的值是否在所有其他列中重复?

如何将图案添加到ggplot中的一个类别

IQR()和stats之间四分位距计算的差异::分位数()在R和' ggpubr '

R创建一个数据透视表,计算多个组的百分比

如果列中存在相同的字符串,则对行值进行总和

编辑文件后编辑RhandsonTable

使用R中相同值创建分组观测指标

ggplot的轴标签保存在officer中时被剪切

自动变更列表

如何将R中数据帧中的任何Nas替换为最后4个值

打印XTS对象

R中边际效应包中Logistic回归的交互作用风险比

为什么我使用geom_density的绘图不能到达x轴?

如何移除GGPlot中超出与面相交的任何格网像元

R+reprex:在呈现R标记文件时创建可重现的示例

警告消息";没有非缺失的参数到min;,正在返回数据中的inf";.表分组集

R -基线图-图形周围的阴影区域

具有自定义仓位限制和计数的GGPLATE直方图

在R中使用ggraph包排列和着色圆