按顺序数字模式匹配列名,并计算所有匹配项的 rowMeans

Match column names by sequential numeric pattern, and calculate rowMeans for all matches

我有一个包含一系列列的数据框,一些列名称与其他列名称完全相同,但在字符串中的某处插入了一个递增的数值(尽管递增的值是随机的)。为了让事情变得更加混乱,列名中可以包含不属于递增系统的数字。我想匹配完全相同的列,除了增加的数字,然后计算这些列的 rowMeans。这是一个示例数据框:

A2<-c(1,2,2,3)
B3<-c(3,4,3,2)
st<-c(1,2,2,3)
ba<-c(3,4,3,2)
Red1bax<-c(3,4,5,6)
Red2bax<-c(2,3,4,NA)
Red7bax<-c(3,4,5,6)
Red1str<-c(3,4,5,6)
Red2str<-c(2,3,4,5)
Red9str<-c(3,4,5,6)
N34_22str<-c(3,4,2,6)
N34_303str<-c(2,4,2,6)

DF<-data.frame(A2,B3,st,ba,N34_303str, Red1str,Red2str, Red7bax, Red2bax, Red9str, Red1bax, N34_22str)

我的目标是计算匹配列的 rowMeans。在这种情况下,匹配的列包含 Red?bax、Red?str 和 N34_?str(? 是递增的数字)。所以理想情况下,我会得到这些列的平均值,然后将它们从数据集中删除。最终结果如下所示:

DF$Redbax<-rowMeans(DF[,c('Red1bax','Red2bax','Red7bax')],na.rm=TRUE)
DF$Redstr<-rowMeans(DF[,c('Red1str','Red2str','Red9str')], na.rm=TRUE)
DF$N34<-rowMeans(DF[,c('N34_22str','N34_303str')], na.rm=TRUE)

DF<-DF[,-c(5:12)]

a data.table 方法使用 .SDcols 和用于列选择的正则表达式模式

library(data.table)
setDT(DF)
DF[, Redbax := rowMeans(.SD, na.rm = TRUE), .SDcols = patterns("^Red.*bax$")]
DF[, Redstr := rowMeans(.SD, na.rm = TRUE), .SDcols = patterns("^Red.*str$")]
DF[, N34 := rowMeans(.SD, na.rm = TRUE), .SDcols = patterns("^N34.*str$")]
#    A2 B3 st ba N34_303str Red1str Red2str Red7bax Red2bax Red9str Red1bax N34_22str   Redbax   Redstr N34
# 1:  1  3  1  3          2       3       2       3       2       3       3         3 2.666667 2.666667 2.5
# 2:  2  4  2  4          4       4       3       4       3       4       4         4 3.666667 3.666667 4.0
# 3:  2  3  2  3          2       5       4       5       4       5       5         2 4.666667 4.666667 2.0
# 4:  3  2  3  2          6       6       5       6      NA       6       6         6 6.000000 5.666667 6.0

我不知道这是你的真实数据还是你的真实数据不同。一般来说,如果您想以自动化方式执行此操作,我们需要想出一种模式来唯一标识每组列。

对于共享的示例,您可以使用此模式 -

cols <- 5:12
gsub('_.*|\d+', '', names(DF)[cols])
#[1] "N"      "Redstr" "Redstr" "Redbax" "Redbax" "Redstr" "Redbax" "N"   

您可以将这些值用作要拆分的组并在 split.default 中使用它,对每个组取行平均并将数据绑定到原始列。

cbind(DF[-cols], 
      sapply(split.default(DF[cols], 
             gsub('_.*|\d+', '', names(DF)[cols])), rowMeans, na.rm = TRUE))

#  A2 B3 st ba   N   Redbax   Redstr
#1  1  3  1  3 2.5 2.666667 2.666667
#2  2  4  2  4 4.0 3.666667 3.666667
#3  2  3  2  3 2.0 4.666667 4.666667
#4  3  2  3  2 6.0 6.000000 5.666667