我有一个看起来像这样的数据框:
df <- data.frame("CB_1.1"=c(0,5,6,2), "CB_1.16"=c(1,5,3,6), "HC_2.11"=c(3,3,4,5), "HC_1.12"=c(2,3,4,5), "HC_1.13"=c(1,0,0,5))
> df
CB_1.1 CB_1.16 HC_2.11 HC_1.12 HC_1.13
1 0 1 3 2 1
2 5 5 3 3 0
3 6 3 4 4 0
4 2 6 5 5 5
我想在“.”之前取共享列名子字符串的行的平均值。产生这样的数据帧:
CB_1 HC_2 HC_1
1 0.5 3 1.5
2 5.0 3 1.5
3 4.5 4 2.0
4 4.0 5 5.0
您会注意到
HC_2.11
列值保持不变,因为没有其他列有 HC_2
在这个数据框中。任何帮助,将不胜感激!
最佳答案
1) 申请/申请 对于每一行,使用名称前缀的 INDEX 和函数 mean
对它使用 tapply .转置结果。不使用任何包。
prefix <- sub("\\..*", "", names(df))
t(apply(df, 1, tapply, prefix, mean))
给出这个矩阵(如果需要数据框结果,请将其包装在 data.frame(...) 中):
CB_1 HC_1 HC_2
[1,] 0.5 1.5 3
[2,] 5.0 1.5 3
[3,] 4.5 2.0 4
[4,] 4.0 5.0 5
2) lm 运行指定的回归。公式中的 +0 表示不添加拦截。系数的转置将是所需的矩阵,
m
.在下一行使名称更好。 prefix
来自(1)。不使用任何包。m <- t(coef(lm(t(df) ~ prefix + 0)))
colnames(m) <- sub("prefix", "", colnames(m))
m
给出这个矩阵
CB_1 HC_1 HC_2
[1,] 0.5 1.5 3
[2,] 5.0 1.5 3
[3,] 4.5 2.0 4
[4,] 4.0 5.0 5
这是根据以下事实得出的:(1) 模型矩阵 X 仅包含 1 和 0,并且 (2) 它的不同列是正交的。模型矩阵如下所示:
X <- model.matrix(~ prefix + 0) # model matrix
X
给予:
prefixCB_1 prefixHC_1 prefixHC_2
1 1 0 0
2 1 0 0
3 0 0 1
4 0 1 0
5 0 1 0
attr(,"assign")
[1] 1 1 1
attr(,"contrasts")
attr(,"contrasts")$prefix
[1] "contr.treatment"
因为模型矩阵的列
X
与 df
的特定行 y 的任何列对应的系数正交( t(df)
的列)只是 sum(x * y) / sum(x * x)
自 x
是一个 0/1 向量,等于 y
的值的平均值对应于 x
中的 1 .3) 堆叠/点击 转换为长格式插入
id
同时列。然后使用 tapply
转换回宽幅tapply-ing mean
.不使用任何包。long <- transform(stack(df), ind = sub("\\..*", "", ind), id = c(row(df)))
with(long, tapply(values, long[c("id", "ind")], mean))
给这张 table 。包裹在
as.data.frame.matrix
如果你想要一个 data.frame。 ind
id CB_1 HC_1 HC_2
1 0.5 1.5 3
2 5.0 1.5 3
3 4.5 2.0 4
4 4.0 5.0 5
关于基于列子串的行均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60694709/