这里是另一种使用基本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)
}
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
matched_sum(x)
AUS1 AUS2 AUS3 AUT1 AUT2 AUT3
15 33 51 60 78 96
函数的作用
col_pattern <- gsub("[0-9]", "", colnames(dfr[col_id]))
在每个列名中查找一个模式。该模式是除数字外的任意字符串。例如:在"AUS1"中的模式为"AUS"。
dfr[grepl(col_pattern, rownames(x)),col_id] <- NA
将NA分配给在第一步中找到模式的列中的任何行。例如,此步骤后的第一列将变为:
AUS1
AUS1 NA
AUS2 NA
AUS3 NA
AUT1 4
AUT2 5
AUT3 6
lapply(1:ncol(dfr), matched_col)
将第一步和第二步应用于数据框中的每一列。
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
colSums(new_dfr, na.rm = TRUE)
会对第4步中创建的数据框中每一列的所有非NA值进行求和。
如果您想保留矩阵结构,可以使用以下代码:
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)
}
matched_sum_mat(x)
AUS1 AUS2 AUS3 AUT1 AUT2 AUT3
15 33 51 60 78 96
更新
如果您想在列名和行名之间实现精确匹配,例如在列名中的"AUS1"和行名中的"AUS1"(而不是"AUS")之间进行匹配,可以通过以下几种方式之一实现:
matched_name_location <- lapply(
colnames(x),
function(a_col_name) rownames(x) %in% a_col_name) |>
unlist() |>
which()
x[matched_name_location] <- NA
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
另一种选择是使用
==
而非
%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
%in%
在这种情况下与使用 ==
得到的结果相同,因为 a_col_name
是一个单一名称。如果使用多个名称,则在 %in%
中忽略名称的顺序,但在 ==
中不会忽略。例如:
y <- c("AUS1", "AUS2" ,"AUS3", "AUT1", "AUT2", "AUT3")
y %in% c("AUS2","AUS1")
y == c("AUS2","AUS1")
另一个选择是使用
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
最后一个函数用于在字符串中查找模式。例如,grepl("AUS1", "AUS10")
返回TRUE
,而"AUS1" %in% "AUS10"
和"AUS1" == "AUS10"
都返回FALSE
。
sapply(split(as.data.frame.table(x), ~ Var2), \(a) with(a, sum(Freq[substr(Var1, 1, 3) != substr(Var2, 1, 3)])))
吗?你已经相当清楚地描述了你的问题,但提供期望的输出将会更有帮助。 - Ritchie Sacramento