首页 > 解决方案 > 根据 R 中 row.name() 的第一部分计算平均值

问题描述

我有一个看起来像这样的数据框:

structure(list(value1 = c(1, 2, 3, 4, 5), value2 = c(1, 2, 2, 
2, 2), value3 = c(1, 1, 2, 3, 4)), class = "data.frame", row.names = c("apple1", 
"apple2", "orange1", "orange2", "plum"))
价值1 价值2 价值3
苹果1 1 1 1
苹果2 2 2 1
橙色1 3 2 2
橙色2 4 2 3
李子 5 2 4

现在我想根据行名的第一部分在每一列上运行 mean 函数(例如,我想独立于他们的苹果号计算苹果组的 value1 的平均值。)我发现像这样的东西有效:

 y<-x[grep("apple",row.names(x)),]
    mean(y$value1)    
    mean(y$value2)
    mean(y$vvalue3)
 y<-x[grep("orange",row.names(x)),]
    mean(y$value1)    
    mean(y$value2)
    mean(y$value2) 
 y<-x[grep("plum",row.names(x)),]
    mean(y$value1)    
    mean(y$value2)
    mean(y$value2) 

但是对于更大的数据集,这将需要很长时间,所以我想知道是否有一种更有效的方法可以根据行名的第一部分对数据进行子集化,然后计算平均值。

标签: raggregate

解决方案


使用tidyverse

library(tidyverse)

df %>% 
  tibble::rownames_to_column("row") %>% 
  dplyr::mutate(row = str_remove(row, "\\d+")) %>% 
  dplyr::group_by(row) %>% 
  dplyr::summarize(across(where(is.numeric), ~ mean(.), .groups = "drop"))

在基地R你可以这样做:

df$row <- gsub("\\d+", "", rownames(df))
data.frame(do.call(cbind, lapply(df[,1:3], function(x) by(x, df$row, mean))))

输出

  row    value1 value2 value3
* <chr>   <dbl>  <dbl>  <dbl>
1 apple     1.5    1.5    1  
2 orange    3.5    2      2.5
3 plum      5      2      4  

数据

df <- structure(list(value1 = 1:5, value2 = c(1, 2, 2, 2, 2), value3 = c(1, 
1, 2, 3, 4)), class = "data.frame", row.names = c("apple1", "apple2", 
"orange1", "orange2", "plum"))

推荐阅读