如何在使用`cbind`函数时保持数据框行的顺序?

huangapple go评论62阅读模式
英文:

How can I keep the order of the row of dataframe while cbinding?

问题

我正在尝试创建一个函数,用于从agricolae包的HSD.test的结果中制作一个整洁的表格。HSD.test的输出是一个列表,其中处理的字母标记按均值降序排序。我想要按T1、T2等顺序排列"均值 ± 标准差 字母"。虽然均值和标准差是按这种方式排列的,但字母没有按照相应的顺序排列。我不能使用以下函数来实现以下目标,因为字母与处理(即下面每个数据框的行名)没有正确对齐。我已经在这里和那里搜索并尝试收集了一些代码片段来制作这个函数。

如何在cbind时保持df3行的顺序?

MyDf<-data.frame(treatment = rep(c('T1','T2','T3','T4'), each = 3),
                 p1 = c(28.5, 21.7, 23.0, 14.9, 10.6, 13.1, 41.8, 39.2, 28.0, 38.2, 40.4, 32.1), 
                 p2 = c(32, 37, 36, 23, 28, 22, 67, 52, 55, 18, 27, 17),
                 p3 = c(5.6, 3.7, 4.9, 7.1, 11.3, 14, 2.3, 5.4, 3.3, 11.6, 10.1, 12)
                 )

MeltMyDf<-melt(MyDf)

MyDfSE<-summarySE(MeltMyDf, measurevar = "value", groupvars = c("variable", "treatment"))

x <- as.character(unique(MyDfSE$variable))

MyModels<-sapply(x, function(my) {lm(value~treatment, data=MeltMyDf, variable==my)}, simplify=FALSE)

MyGroups<- lapply(MyModels, function(m) HSD.test((m), "treatment", alpha = 0.05, group = TRUE, console = FALSE, variable==variable))

#---- 我创建的函数 ------------
make_HSD_table<-function(HSDlist){
  
  mycolnames<-names(HSDlist)
  mycolnumber<-length(mycolnames)
  
  df1<-as.data.frame(lapply(lapply(HSDlist, '[[', 'means'), '[', 'value'))
  df1[order(row.names(df1)), ]
  df1<-round(df1, digits = 2)
  
  df2<-as.data.frame(lapply(lapply(HSDlist, '[[', 'means'), '[', c('std')))
  df2[order(row.names(df2)), ]
  df2<-round(df2, digits = 2)
  
  df3<-as.data.frame(lapply(lapply(HSDlist, '[[', 'groups'), '[', 'groups'))
  df3[order(row.names(df3)), ]

  myrownumber<-nrow(df1)
  pm_df<-data.frame(replicate(mycolnumber, rep('±', myrownumber))
  
  my_table <- cbind(df1, pm_df, df2, df3)[order(c(seq_along(df1), seq_along(pm_df),seq_along(df2), seq_along(df3)))]
  
  
  my_table <- cbind(sapply(split.default(my_table, as.integer(gl(ncol(my_table), 4, ncol(my_table))), function(x) do.call(paste, x)))
  
  colnames(my_table)<-mycolnames
  rownames(my_table)<-rownames(df1)

  write.table(my_table, 'my_HSD_table.csv', append = F, sep = ',', row.names = FALSE)
  
  return(my_table)
}

#-----------------------------------------
make_HSD_table(MyGroups)

如您所见,值±标准差是根据处理排序的。但字母没有排序并且与错误的均值±标准差放在一起!

英文:

I am trying to make a function for making a neat table from the result of HSD.test from the agricolae package. The output of the HSD.test is a list where the treatment lettering is sorted in descending order of the mean. I would like to arrange "mean ± sd letter' by T1, T2,... so on. Though mean and sd are arranged this way, the lettering does not follow the order. I cannot accomplish the following with the following function, as the letters are not aligned properly with the treatment (which is the row names in each data frame below). I have searched here and there and tried to collected code fragments to make the function so far.

How can I keep the order of the row of df3 during cbinding?

MyDf&lt;-data.frame(treatment = rep(c(&#39;T1&#39;,&#39;T2&#39;,&#39;T3&#39;,&#39;T4&#39;), each = 3),
                 p1 = c(28.5, 21.7, 23.0, 14.9, 10.6, 13.1, 41.8, 39.2, 28.0, 38.2, 40.4, 32.1), 
                 p2 = c(32, 37, 36, 23, 28, 22, 67, 52, 55, 18, 27, 17),
                 p3 = c(5.6, 3.7, 4.9, 7.1, 11.3, 14, 2.3, 5.4, 3.3, 11.6, 10.1, 12)
                 )

MeltMyDf&lt;-melt(MyDf)

MyDfSE&lt;-summarySE(MeltMyDf, measurevar = &quot;value&quot;, groupvars = c(&quot;variable&quot;, &quot;treatment&quot;))

x &lt;- as.character(unique(MyDfSE$variable))

MyModels&lt;-sapply(x, function(my) {lm(value~treatment, data=MeltMyDf, variable==my)}, simplify=FALSE)

MyGroups&lt;- lapply(MyModels, function(m) HSD.test((m), &quot;treatment&quot;, alpha = 0.05, group = TRUE, console = FALSE, variable==variable))

#---- the function I have created ------------
make_HSD_table&lt;-function(HSDlist){
  
  mycolnames&lt;-names(HSDlist)
  mycolnumber&lt;-length(mycolnames)
  
  df1&lt;-as.data.frame(lapply(lapply(HSDlist, `[[`, &#39;means&#39;), &#39;[&#39;, &#39;value&#39;))
  df1[order(row.names(df1)), ]
  df1&lt;-round(df1, digits = 2)
  
  df2&lt;-as.data.frame(lapply(lapply(HSDlist, `[[`, &#39;means&#39;), &#39;[&#39;, c(&#39;std&#39;)))
  df2[order(row.names(df2)), ]
  df2&lt;-round(df2, digits = 2)
  
  df3&lt;-as.data.frame(lapply(lapply(HSDlist, `[[`, &#39;groups&#39;), &#39;[&#39;, &#39;groups&#39;))
  df3[order(row.names(df3)), ]

  myrownumber&lt;-nrow(df1)
  pm_df&lt;-data.frame(replicate(mycolnumber, rep(&#39;&#177;&#39;, myrownumber)))
  
  my_table &lt;- cbind(df1, pm_df, df2, df3)[order(c(seq_along(df1), seq_along(pm_df),seq_along(df2), seq_along(df3)))]
  
  
  my_table &lt;- cbind(sapply(split.default(my_table, as.integer(gl(ncol(my_table), 4, ncol(my_table)))), function(x) do.call(paste, x)))
  
  colnames(my_table)&lt;-mycolnames
  rownames(my_table)&lt;-rownames(df1)

  write.table(my_table, &#39;my_HSD_table.csv&#39;, append = F, sep = &#39;,&#39;, row.names = FALSE)
  
  return(my_table)
}

#-----------------------------------------
make_HSD_table(MyGroups)

   p1                p2               p3             
T1 &quot;24.4 &#177; 3.61 a&quot;   &quot;35 &#177; 2.65 a&quot;    &quot;4.73 &#177; 0.96 a&quot;
T2 &quot;12.87 &#177; 2.16 ab&quot; &quot;24.33 &#177; 3.21 b&quot; &quot;10.8 &#177; 3.48 a&quot;
T3 &quot;36.33 &#177; 7.33 bc&quot; &quot;58 &#177; 7.94 bc&quot;   &quot;3.67 &#177; 1.58 b&quot;
T4 &quot;36.9 &#177; 4.3 c&quot;    &quot;20.67 &#177; 5.51 c&quot; &quot;11.23 &#177; 1 b&quot;  

**As you can see, the values&#177;sd are sorted according to the treatment. But the letters are not sorted and placed with wrong mean&#177;sd!**

答案1

得分: 0

以下是翻译好的部分:

最后,我可以修正我的函数,以从按数据框顺序排序的 `HSD.test` 生成 `mean &#177; sd grouping_letter` 表格的输出。以下是工作流程:
MyDf <- data.frame(treatment = rep(c('T1', 'T2', 'T3', 'T4'), each = 3),
p1 = c(28.5, 21.7, 23.0, 14.9, 10.6, 13.1, 41.8, 39.2, 28.0, 38.2, 40.4, 32.1), 
p2 = c(32, 37, 36, 23, 28, 22, 67, 52, 55, 18, 27, 17),
p3 = c(5.6, 3.7, 4.9, 7.1, 11.3, 14, 2.3, 5.4, 3.3, 11.6, 10.1, 12)
)
MeltMyDf <- melt(MyDf)
MyDfSE <- summarySE(MeltMyDf, measurevar = "value", groupvars = c("variable", "treatment"))
x <- as.character(unique(MyDfSE$variable))
MyModels <- sapply(x, function(my) {lm(value ~ treatment, data = MeltMyDf, variable == my)}, simplify = FALSE)
MyGroups <- lapply(MyModels, function(m) HSD.test((m), "treatment", alpha = 0.05, group = TRUE, console = FALSE, variable == variable))

现在,用于调用表格的函数。它还将表格导出为 csv 文件。

make_HSD_table <- function(HSDlist){
mycolnames <- names(HSDlist)
mycolnumber <- length(mycolnames)
df1 <- as.data.frame(lapply(lapply(HSDlist, '[[', 'means'), '[', 'value'))
df1[order(row.names(df1)), ]
df1 <- round(df1, digits = 2)
df2 <- as.data.frame(lapply(lapply(HSDlist, '[[', 'means'), '[', c('std')))
df2[order(row.names(df2)), ]
df2 <- round(df2, digits = 2)
df3 <- lapply(lapply(HSDlist, '[[', 'groups'), '[', 'groups')
df3 <- Map(cbind, df3, my_row_names = lapply(df3, rownames))
df3 <- lapply(df3, function(df) {df[order(df$my_row_names), ]})
df3 <- lapply(df3, function(x) x[,1])
myrownumber <- nrow(df1)
pm_df <- data.frame(replicate(mycolnumber, rep('&#177;', myrownumber)))
my_table <- cbind(df1, pm_df, df2, df3)[order(c(seq_along(df1), seq_along(pm_df), seq_along(df2), seq_along(df3)))]
my_table <- cbind(sapply(split.default(my_table, as.integer(gl(ncol(my_table), 4, ncol(my_table))), function(x) do.call(paste, x)))
colnames(my_table) <- mycolnames
my_table <- data.frame(treatment = rownames(df1), my_table)
write.table(my_table, 'my_HSD_table.csv', append = F, sep = ',', row.names = FALSE)
return(my_table)
}

让我们从 HSD.test 输出中生成表格。

make_HSD_table(MyGroups)
treatment              p1              p2            p3
1        T1  24.4 &#177; 3.61 bc     35 &#177; 2.65 b 4.73 &#177; 0.96 b
2        T2  12.87 &#177; 2.16 c 24.33 &#177; 3.21 bc 10.8 &#177; 3.48 a
3        T3 36.33 &#177; 7.33 ab     58 &#177; 7.94 a 3.67 &#177; 1.58 b
4        T4    36.9 &#177; 4.3 a  20.67 &#177; 5.51 c   11.23 &#177; 1 a

如您所见,字母已正确分配到相应的 mean&#177;sd 列中。

英文:

Finally, I could correct my function to make an output of mean &#177; sd grouping_letter table from HSD.test which is sorted in the order of data frame. Here is the workflow:

library(reshape2)
library(Rmisc)
library(agricolae)
library(dplyr)
library(stringr)
MyDf&lt;-data.frame(treatment = rep(c(&#39;T1&#39;,&#39;T2&#39;,&#39;T3&#39;,&#39;T4&#39;), each = 3),
p1 = c(28.5, 21.7, 23.0, 14.9, 10.6, 13.1, 41.8, 39.2, 28.0, 38.2, 40.4, 32.1), 
p2 = c(32, 37, 36, 23, 28, 22, 67, 52, 55, 18, 27, 17),
p3 = c(5.6, 3.7, 4.9, 7.1, 11.3, 14, 2.3, 5.4, 3.3, 11.6, 10.1, 12)
)
MeltMyDf&lt;-melt(MyDf)
MyDfSE&lt;-summarySE(MeltMyDf, measurevar = &quot;value&quot;, groupvars = c(&quot;variable&quot;, &quot;treatment&quot;))
x &lt;- as.character(unique(MyDfSE$variable))
MyModels&lt;-sapply(x, function(my) {lm(value~treatment, data=MeltMyDf, variable==my)}, simplify=FALSE)
MyGroups&lt;- lapply(MyModels, function(m) HSD.test((m), &quot;treatment&quot;, alpha = 0.05, group = TRUE, console = FALSE, variable==variable))

Now, the function for calling the table. It will also export the table as a csv file.

make_HSD_table&lt;-function(HSDlist){
mycolnames&lt;-names(HSDlist)
mycolnumber&lt;-length(mycolnames)
df1&lt;-as.data.frame(lapply(lapply(HSDlist, `[[`, &#39;means&#39;), &#39;[&#39;, &#39;value&#39;))
df1[order(row.names(df1)), ]
df1&lt;-round(df1, digits = 2)
df2&lt;-as.data.frame(lapply(lapply(HSDlist, `[[`, &#39;means&#39;), &#39;[&#39;, c(&#39;std&#39;)))
df2[order(row.names(df2)), ]
df2&lt;-round(df2, digits = 2)
df3&lt;-lapply(lapply(HSDlist, `[[`, &#39;groups&#39;), &#39;[&#39;, &#39;groups&#39;)
df3&lt;-Map(cbind, df3, my_row_names = lapply(df3, rownames))
df3&lt;-lapply(df3, function(df) {df[order(df$my_row_names), ]})
df3&lt;-lapply(df3, function(x) x[,1])
myrownumber&lt;-nrow(df1)
pm_df&lt;-data.frame(replicate(mycolnumber, rep(&#39;&#177;&#39;, myrownumber)))
my_table &lt;- cbind(df1, pm_df, df2, df3)[order(c(seq_along(df1), seq_along(pm_df),seq_along(df2), seq_along(df3)))]
my_table &lt;- cbind(sapply(split.default(my_table, as.integer(gl(ncol(my_table), 4, ncol(my_table)))), function(x) do.call(paste, x)))
colnames(my_table)&lt;-mycolnames
my_table&lt;-data.frame(treatment = rownames(df1), my_table)
write.table(my_table, &#39;my_HSD_table.csv&#39;, append = F, sep = &#39;,&#39;, row.names = FALSE)
return(my_table)
}

Let's make the table from HSD.test output.

make_HSD_table(MyGroups)
treatment              p1              p2            p3
1        T1  24.4 &#177; 3.61 bc     35 &#177; 2.65 b 4.73 &#177; 0.96 b
2        T2  12.87 &#177; 2.16 c 24.33 &#177; 3.21 bc 10.8 &#177; 3.48 a
3        T3 36.33 &#177; 7.33 ab     58 &#177; 7.94 a 3.67 &#177; 1.58 b
4        T4    36.9 &#177; 4.3 a  20.67 &#177; 5.51 c   11.23 &#177; 1 a

As you can see, the letters have been properly assigned to the respective mean&#177;sd columns.

huangapple
  • 本文由 发表于 2023年3月7日 03:06:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75654845.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定