【问题标题】:Calculate mean based on first part of row.name() in R根据 R 中 row.name() 的第一部分计算平均值
【发布时间】:2021-04-12 14:39:36
【问题描述】:

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

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"))
value1 value2 value3
apple1 1 1 1
apple2 2 2 1
orange1 3 2 2
orange2 4 2 3
plum 5 2 4

现在我想根据行名的第一部分在每一列上运行均值函数 (例如,我想独立于他们的苹果号计算苹果组的 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) 

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

【问题讨论】:

  • 请提供使用dput(y) 粘贴到问题中的数据样本,这将使您的问题可重现并允许测试答案。 minimal reproducible example

标签: r aggregate


【解决方案1】:

使用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"))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 2017-03-07
    • 2020-06-05
    相关资源
    最近更新 更多