我有这样的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"))])
向更好的替代解决方案开放,或者根据我上面尝试过的方法来解决这个问题。
答案 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)