基于列名

时间:2018-05-29 16:06:24

标签: r

我有这样的df

abc_vs_b_h_wh_rt_8_pnum <- c(4,3,6,4,1)
defj_vs_b_h_wh_rt_9_pnum <- c(6,2,1,4,3)
ghi_vs_b_h_wh_rt_10_pnum <- c(9,0,5,3,2)
abc_vs_p_h_wh_rt_9_bnum <- c(5,2,3,1,4)
defj_vs_p_h_wh_rt_10_bnum <- c(7,7,4,2,1)
ghi_vs_p_h_wh_rt_11_bnum <- c(1,3,2,4,2)
abc_vs_p_h_wh_rt_8_bnum <- c(1,5,3,2,6)
defj_vs_p_h_wh_rt_9_bnum <- c(2,2,4,3,1)
ghi_vs_p_h_wh_rt_10_bnum <- c(1,1,0,2,3)
df <- data.frame(abc_vs_b_h_wh_rt_8_pnum,defj_vs_b_h_wh_rt_9_pnum,ghi_vs_b_h_wh_rt_10_pnum,abc_vs_p_h_wh_rt_8_bnum,defj_vs_p_h_wh_rt_9_bnum,ghi_vs_p_h_wh_rt_10_bnum,abc_vs_p_h_wh_rt_9_bnum,defj_vs_p_h_wh_rt_10_bnum,ghi_vs_p_h_wh_rt_11_bnum)

我想创建一个新的df,其中包含每对相应bnum / pnum列的平均值。

例如,abc_vs_b_h_wh_rt_8_pnum将与abc_vs_p_h_wh_rt_8_bnum取平均值,因为它们都以相同的字符串开头,并且在_bnum / _pnum之前具有相同的数字。

我的输出如下:

abc_wh_rt_8 <- c(2.5,4,4.5,3,3.5)
defj_wh_rt_9 <- c(4,2,2.5,3.5,2)
ghi_wh_rt_10 <- c(5,.5,2.5,2.5,2.5)
df2 <- data.frame(abc_wh_rt_8,defj_wh_rt_9,ghi_wh_rt_10)

我试图通过拆分列名并使用rowMeans来做到这一点,但我很难让它发挥作用。

colnames1 <- sapply(strsplit(names(df),"_vs",fixed=TRUE),"[",1)
colnames2 <- sapply(strsplit(sapply(strsplit(names(df),"rt_",fixed=TRUE),
    "[",2),"num",fixed=TRUE),"[",1)
result <- rowMeans(df[,which(names(df)==paste0(colnames1,"_vs_b_h_",colnames2,
    "num") | names(df)==paste0(colnames1,"_vs_p_h_",colnames2,"num"))])

向更好的替代解决方案开放,或者根据我上面尝试过的方法来解决这个问题。

1 个答案:

答案 0 :(得分:0)

另一种解决方案是使用tidyverse,并更改结构以使数据高而瘦,然后可以更轻松地使用列名:

library(dplyr)
library(tidyr)
library(tibble)

df2 <- 
  df %>% 
  rowid_to_column() %>% 
  gather(ColName, ResultValue, -rowid) %>% 
  separate(ColName, c("ColName2", "BPNum"), -5) %>% 
  mutate(ColName2 = gsub("vs_[bp]_","",ColName2, perl = TRUE)) %>% 
  group_by(rowid, ColName2) %>% 
  summarise(Mean=mean(ResultValue)) %>% 
  ungroup() %>% 
  spread(ColName2, Mean) %>% 
  select(-rowid)