计算数据框中各列平均值的快捷方式
Shortcut to calculate the mean of columns in a data frame
我有以下数据框:
Gene <- c("1","2","3","4","5","6")
> A1.1 <- c(1,1,2,4,3,5)
> A1.2 <- c(1,2,3,4,5,6)
> B1.1 <- c(2,2,3,5,5,5)
> B1.2 <- c(1,2,3,5,5,5)
> A2.1 <- c(3,2,5,6,6,6)
> A2.2 <- c(1,1,2,2,4,6)
> B2.1 <- c(2,1,4,5,7,4)
> B2.2 <- c(1,3,4,5,2,3)
> df <- data.frame(Gene,A1.1,A1.2,B1.1,B1.2,A2.1,A2.2,B2.1,B2.2)
> df
Gene A1.1 A1.2 B1.1 B1.2 A2.1 A2.2 B2.1 B2.2
1 1 1 1 2 1 3 1 2 1
2 2 1 2 2 2 2 1 1 3
3 3 2 3 3 3 5 2 4 4
4 4 4 4 5 5 6 2 5 5
5 5 3 5 5 5 6 4 7 2
6 6 5 6 5 5 6 6 4 3
我希望计算每个基因(行)的相同 letter/number 样本(列)的平均值。
即。计算两个 A1 样本、两个 A2 样本、两个 B1 样本和两个 B2 样本的每个基因 (#1-6) 的平均值。
我知道我可以使用 apply()
来做这件事
例如,
> A1_df <- data.frame(df$A1.1, df$A1.2)
> A1 <- apply(A1_df, 1, mean)
> A1
[1] 1.0 1.5 2.5 4.0 4.0 5.5
但是有没有使用 sapply()
的快捷方式,这样我最终得到一个新的数据框,其中的列现在是“A1”、“A2”、“B1”、“B2” ?
如果有任何不清楚的地方,请告诉我
谢谢
这里,我们可以在数字列上使用split.default
,通过删除列名中的.
和它后面的数字拆分成data.frame的列表,然后循环用 sapply
超过 list
并用 rowMeans
得到 mean
sapply(split.default(df[-1], sub("\.\d+", "", names(df)[-1])), rowMeans)
-输出
A1 A2 B1 B2
1 1.0 2.0 1.5 1.5
2 1.5 1.5 2.0 2.0
3 2.5 3.5 3.0 4.0
4 4.0 4.0 5.0 5.0
5 4.0 5.0 5.0 4.5
6 5.5 6.0 5.0 3.5
或使用 pivot_longer
重塑为 'long' 格式并按 mean
分组。在这里,names_pattern
正在捕获 ((.*)
) .
之前的字符和列名中的数字,这将是以长格式创建的 .value
列
library(dplyr)
library(tidyr)
df %>%
pivot_longer(cols = -Gene, names_to = ".value",
names_pattern = "(.*)\.\d+") %>%
group_by(Gene) %>%
summarise(across(everything(), mean))
# A tibble: 6 × 5
Gene A1 B1 A2 B2
<int> <dbl> <dbl> <dbl> <dbl>
1 1 1 1.5 2 1.5
2 2 1.5 2 1.5 2
3 3 2.5 3 3.5 4
4 4 4 5 4 5
5 5 4 5 5 4.5
6 6 5.5 5 6 3.5
数据
df <- structure(list(Gene = 1:6, A1.1 = c(1L, 1L, 2L, 4L, 3L, 5L),
A1.2 = 1:6, B1.1 = c(2L, 2L, 3L, 5L, 5L, 5L), B1.2 = c(1L,
2L, 3L, 5L, 5L, 5L), A2.1 = c(3L, 2L, 5L, 6L, 6L, 6L), A2.2 = c(1L,
1L, 2L, 2L, 4L, 6L), B2.1 = c(2L, 1L, 4L, 5L, 7L, 4L), B2.2 = c(1L,
3L, 4L, 5L, 2L, 3L)), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6"))
我有以下数据框:
Gene <- c("1","2","3","4","5","6")
> A1.1 <- c(1,1,2,4,3,5)
> A1.2 <- c(1,2,3,4,5,6)
> B1.1 <- c(2,2,3,5,5,5)
> B1.2 <- c(1,2,3,5,5,5)
> A2.1 <- c(3,2,5,6,6,6)
> A2.2 <- c(1,1,2,2,4,6)
> B2.1 <- c(2,1,4,5,7,4)
> B2.2 <- c(1,3,4,5,2,3)
> df <- data.frame(Gene,A1.1,A1.2,B1.1,B1.2,A2.1,A2.2,B2.1,B2.2)
> df
Gene A1.1 A1.2 B1.1 B1.2 A2.1 A2.2 B2.1 B2.2
1 1 1 1 2 1 3 1 2 1
2 2 1 2 2 2 2 1 1 3
3 3 2 3 3 3 5 2 4 4
4 4 4 4 5 5 6 2 5 5
5 5 3 5 5 5 6 4 7 2
6 6 5 6 5 5 6 6 4 3
我希望计算每个基因(行)的相同 letter/number 样本(列)的平均值。
即。计算两个 A1 样本、两个 A2 样本、两个 B1 样本和两个 B2 样本的每个基因 (#1-6) 的平均值。
我知道我可以使用 apply()
例如,
> A1_df <- data.frame(df$A1.1, df$A1.2)
> A1 <- apply(A1_df, 1, mean)
> A1
[1] 1.0 1.5 2.5 4.0 4.0 5.5
但是有没有使用 sapply()
的快捷方式,这样我最终得到一个新的数据框,其中的列现在是“A1”、“A2”、“B1”、“B2” ?
如果有任何不清楚的地方,请告诉我
谢谢
这里,我们可以在数字列上使用split.default
,通过删除列名中的.
和它后面的数字拆分成data.frame的列表,然后循环用 sapply
超过 list
并用 rowMeans
mean
sapply(split.default(df[-1], sub("\.\d+", "", names(df)[-1])), rowMeans)
-输出
A1 A2 B1 B2
1 1.0 2.0 1.5 1.5
2 1.5 1.5 2.0 2.0
3 2.5 3.5 3.0 4.0
4 4.0 4.0 5.0 5.0
5 4.0 5.0 5.0 4.5
6 5.5 6.0 5.0 3.5
或使用 pivot_longer
重塑为 'long' 格式并按 mean
分组。在这里,names_pattern
正在捕获 ((.*)
) .
之前的字符和列名中的数字,这将是以长格式创建的 .value
列
library(dplyr)
library(tidyr)
df %>%
pivot_longer(cols = -Gene, names_to = ".value",
names_pattern = "(.*)\.\d+") %>%
group_by(Gene) %>%
summarise(across(everything(), mean))
# A tibble: 6 × 5
Gene A1 B1 A2 B2
<int> <dbl> <dbl> <dbl> <dbl>
1 1 1 1.5 2 1.5
2 2 1.5 2 1.5 2
3 3 2.5 3 3.5 4
4 4 4 5 4 5
5 5 4 5 5 4.5
6 6 5.5 5 6 3.5
数据
df <- structure(list(Gene = 1:6, A1.1 = c(1L, 1L, 2L, 4L, 3L, 5L),
A1.2 = 1:6, B1.1 = c(2L, 2L, 3L, 5L, 5L, 5L), B1.2 = c(1L,
2L, 3L, 5L, 5L, 5L), A2.1 = c(3L, 2L, 5L, 6L, 6L, 6L), A2.2 = c(1L,
1L, 2L, 2L, 4L, 6L), B2.1 = c(2L, 1L, 4L, 5L, 7L, 4L), B2.2 = c(1L,
3L, 4L, 5L, 2L, 3L)), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6"))