[英]How to average every two rows of dataframe in R
我有以下數據框(包含 1000 列):
df<- structure(c(1, 2, 2, 1, 2, 2, 2, 1, 3, 3, 2, 2),
.Dim = 4:3, .Dimnames = list(c("a", "b", "c", "d"),
c("t1", "t2", "t3")))
什么是獲得每兩行平均值的有效方法?
我想要的結果:
t1 t2 t3
a 1 2 3
b 2 2 3
a_b 1.5 2 3
c 2 2 2
d 1 1 2
c_d 1.5 1.5 2
拆分為 2 行,然后獲得每列的平均值,然后 rbind 和 rbind 再次全部。
do.call(rbind,
lapply(seq(1, nrow(df), 2), function(i){
x <- df[ i:(i + 1), , drop = FALSE]
res <- rbind(x, colSums(x)/2)
rownames(res)[ nrow(res) ] <- paste(rownames(x), collapse = "_")
res
}))
# t1 t2 t3
# a 1.0 2.0 3
# b 2.0 2.0 3
# a_b 1.5 2.0 3
# c 2.0 2.0 2
# d 1.0 1.0 2
# c_d 1.5 1.5 2
一種dplyr
可能性可能是:
df %>%
data.frame() %>%
rownames_to_column() %>%
mutate_if(is.factor, as.numeric) %>%
group_by(group = gl(n()/2, 2)) %>%
group_map(~ bind_rows(.x, tibble(rowname = paste(.x$rowname, collapse = "_"),
t1 = mean(.x$t1),
t2 = mean(.x$t2),
t3 = mean(.x$t3)))) %>%
ungroup() %>%
select(-group)
rowname t1 t2 t3
<chr> <dbl> <dbl> <dbl>
1 a 1 2 2
2 b 2 2 2
3 a_b 1.5 2 2
4 c 2 2 1
5 d 1 1 1
6 c_d 1.5 1.5 1
如果您事先將前三行創建為data.frame
,將名稱作為列,將因子作為數字變量,則可以省略前三行。 然后,它的作用是,首先使用gl()
創建一個分組變量。 其次,它計算均值,將名稱創建為組中兩個元素的組合,並將其與原始數據綁定。 最后,它取消分組並刪除冗余變量。
另一種dplyr
方法。
更新:如果您確實需要行名稱( a
、 b
、 a_b
等),請參閱我的原始解決方案以獲得可擴展但更復雜的版本。
原來的
df <- df %>% as_tibble()
n <- nrow(df)/2
orig <- df %>% mutate(grp = sort(rep(1:2, n)))
means <- orig %>% group_by(grp) %>% summarise_all(mean)
bind_rows(orig, means) %>% arrange(grp) %>% select(-grp)
輸出:
# A tibble: 6 x 3
t1 t2 t3
<dbl> <dbl> <dbl>
1 1 2 3
2 2 2 3
3 1.5 2 3
4 2 2 2
5 1 1 2
6 1.5 1.5 2
更新了行名稱
rnames <- row.names(df)
df <- df %>% as_tibble()
n <- (nrow(df)/2)
orig <- df %>%
mutate(grp = sort(rep(1:n, n)), rn = rnames)
means <- orig %>%
group_by(grp) %>%
mutate(rn = paste0(rn, collapse="_")) %>%
ungroup() %>%
group_by(rn) %>%
summarise_if(is.numeric, mean)
bind_rows(orig, means) %>% arrange(grp) %>% select(-grp)
輸出:
t1 t2 t3 rn
<dbl> <dbl> <dbl> <chr>
1 1 2 3 a
2 2 2 3 b
3 1.5 2 3 a_b
4 2 2 2 c
5 1 1 2 d
6 1.5 1.5 2 c_d
適用於任意數量列的base
R 解決方案
M <- matrix(unlist(c(df)), ncol = 2, byrow = TRUE)
M <- cbind(M, rowMeans(M))
M <- matrix(c(t(M)),ncol = ncol(df), byrow = FALSE)
# add row names and column names
row.names <- matrix(rownames(df), ncol = 2 ,byrow = TRUE)
rownames(M) <- c(t(cbind(row.names, apply(row.names,1, paste, collapse = "_"))))
colnames(M) <- colnames(df)
# t1 t2 t3
# a 1.0 2.0 3
# b 2.0 2.0 3
# a_b 1.5 2.0 3
# c 2.0 2.0 2
# d 1.0 1.0 2
# c_d 1.5 1.5 2
一種可能性是使用dplyr
包。 請注意,我使用的數據與您使用的數據略有不同:在您的數據中,數字實際上是字符值。
df <- structure(c(1, 2, 2, 1, 2, 2, 2, 1, 3, 3, 2, 2),
.Dim = 4:3, .Dimnames = list(c("a", "b", "c", "d"),
c("t1", "t2", "t3")))
首先,我創建摘要標題(包含均值)。
library(dplyr)
df_summary <- df %>% as_tibble(rownames = "names") %>%
group_by(ceiling(1:n() / 2)) %>%
summarise(names = paste(names, collapse = "_"),
t1 = mean(t1),
t2 = mean(t2),
t3 = mean(t3)) %>%
select(-1)
# A tibble: 2 x 4
names t1 t2 t3
<chr> <dbl> <dbl> <dbl>
1 a_b 1.5 2 3
2 c_d 1.5 1.5 2
然后我將匯總數據與原始數據結合起來:
df_summary %>% bind_rows(df %>% as_tibble(rownames = "names")) %>%
slice(3, 4, 1, 5, 6, 2)
# A tibble: 6 x 4
names t1 t2 t3
<chr> <dbl> <dbl> <dbl>
1 a 1 2 3
2 b 2 2 3
3 a_b 1.5 2 3
4 c 2 2 2
5 d 1 1 2
6 c_d 1.5 1.5 2
這個 function 基於名為“組”的列的平均值,應該在數據集中。 x 是數據框或矩陣。
rowm = function(x){
x = as.data.frame(x)
u = unique(x$group)
r = rep(NA, ncol(x)*length(u))
tempDF = matrix(r, ncol=ncol(x))
counter=0
for(i in u){
counter = counter+1
tempDF[counter, ] = colMeans(x[x$group==i, ], )
}
colnames(tempDF) = colnames(x)
return(tempDF)}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.