将行旋转到列中

时间:2010-09-30 22:30:14

标签: r reshape

假设(为了简化)我有一个包含一些控制与治疗数据的表:

Which, Color, Response, Count
Control, Red, 2, 10
Control, Blue, 3, 20
Treatment, Red, 1, 14
Treatment, Blue, 4, 21

对于每种颜色,我想要一行包含对照和治疗数据,即:

Color, Response.Control, Count.Control, Response.Treatment, Count.Treatment
Red, 2, 10, 1, 14
Blue, 3, 20, 4, 21

我想这样做的一种方法是在每个控件/处理子集上使用内部合并(在Color列上合并),但是有更好的方法吗?我在想重塑包或堆栈功能可以某种方式来做,但我不确定。

4 个答案:

答案 0 :(得分:19)

使用重塑包。

首先,融化你的data.frame:

x <- melt(df) 

然后演员:

dcast(x, Color ~ Which + variable)

根据您正在使用的reshape包的版本,可能是cast()(重塑)或dcast()(reshape2)

瞧。

答案 1 :(得分:6)

cast包中的reshape函数(不要与基础R中的reshape函数混淆)可以执行此操作以及许多其他操作。见这里:http://had.co.nz/reshape/

答案 2 :(得分:6)

添加选项(多年后)....

基本R中的典型方法涉及reshape函数(由于需要时间掌握的众多参数,这通常不受欢迎)。它对于较小的数据集来说是一个非常有效的函数,但并不总能很好地扩展。

reshape(mydf, direction = "wide", idvar = "Color", timevar = "Which")
#   Color Response.Control Count.Control Response.Treatment Count.Treatment
# 1   Red                2            10                  1              14
# 2  Blue                3            20                  4              21

已经涵盖了来自&#34;重塑&#34;的cast / dcast。和&#34; reshape2&#34; (现在,来自&#34; data.table&#34;的dcast.data.table,在拥有大型数据集时尤其有用)。但也来自Hadleyverse,那里有&#34; tidyr&#34;,它与&#34; dplyr&#34;包:

library(tidyr)
library(dplyr)
mydf %>%
  gather(var, val, Response:Count) %>%  ## make a long dataframe
  unite(RN, var, Which) %>%             ## combine the var and Which columns
  spread(RN, val)                       ## make the results wide
#   Color Count_Control Count_Treatment Response_Control Response_Treatment
# 1  Blue            20              21                3                  4
# 2   Red            10              14                2                  1

另外需要注意的是,在即将推出的&#34; data.table&#34;版本中,dcast.data.table函数应该能够处理此问题而无需先melt你的数据。

data.table的{​​{1}}实现允许您将多列转换为宽格式而不首先将其熔化,如下所示:

dcast

答案 3 :(得分:3)

Reshape确实可以将瘦的数据框(例如,从简单的SQL查询)转换为宽矩阵,并且非常灵活,但速度很慢。对于大量数据,非常非常慢。幸运的是,如果你只想转向一个固定的形状,那么编写一个小C函数来快速进行转换是相当容易的。

在我的例子中,使用3列和672,338行旋转瘦数据框需要34秒重塑,使用我的R代码需要25秒,使用C需要2.3秒。具有讽刺意味的是,C实现可能比我更容易编写(调整速度)R实施。

这是用于旋转浮点数的核心C代码。请注意,它假设您已经在调用C代码之前在R 中分配了正确大小的结果矩阵,这导致R-devel人员惊恐地颤抖:

#include <R.h> 
#include <Rinternals.h> 
/* 
 * This mutates the result matrix in place.
 */
SEXP
dtk_pivot_skinny_to_wide(SEXP n_row  ,SEXP vi_1  ,SEXP vi_2  ,SEXP v_3  ,SEXP result)
{
   int ii, max_i;
   unsigned int pos;
   int nr = *INTEGER(n_row);
   int * aa = INTEGER(vi_1);
   int * bb = INTEGER(vi_2);
   double * cc = REAL(v_3);
   double * rr = REAL(result);
   max_i = length(vi_2);
   /*
    * R stores matrices by column.  Do ugly pointer-like arithmetic to
    * map the matrix to a flat vector.  We are translating this R code:
    *    for (ii in 1:length(vi.2))
    *       result[((n.row * (vi.2[ii] -1)) + vi.1[ii])] <- v.3[ii]
    */
   for (ii = 0; ii < max_i; ++ii) {
      pos = ((nr * (bb[ii] -1)) + aa[ii] -1);
      rr[pos] = cc[ii];
      /* printf("ii: %d \t value: %g \t result index:  %d \t new value: %g\n", ii, cc[ii], pos, rr[pos]); */
   }
   return(result);
}