【问题标题】:Long to wide transformation with column headings converted to data points [duplicate]将列标题转换为数据点的长到宽转换[重复]
【发布时间】:2017-01-17 12:44:24
【问题描述】:

我有一个“宽”数据框,其中包含日期作为列标题。使用转换功能,我可以把它变成一个“长”的数据框。但是,我需要将日期(列标题)作为新变量作为实际数据点。让我用一个类似的数据框来说明这个问题:

matrix <- matrix(round(runif(25)*10), nrow = 5, ncol = 5)
hospital_names <- c("Hosp A", "Hosp B", "Hosp C", "Hosp D", "Hosp E")
dates <- c("Jan 03", "Feb 03", "Mar 03", "Apr 03", "May 03")
df <- as.data.frame(matrix)
colnames(df) =  dates
df <- cbind(hospital_names, df)

这给出了一个如下所示的数据框:

  hospital_names Jan 03 Feb 03 Mar 03 Apr 03 May 03 
 1 Hosp A          10      3      1      9      2        
 2 Hosp B           8      5      8      6      0          
 3 Hosp C           9      1      9      2      5         
 4 Hosp D           4      0      7      0      4         
 5 Hosp E           0      8      9      2      4

我现在应用变换函数:

 df <- t(df)

得到这个:

                [,1]     [,2]     [,3]     [,4]     [,5]    
 hospital_names "Hosp A" "Hosp B" "Hosp C" "Hosp D" "Hosp E"
 Jan 03         "10"     "8"      "9"      "4"      "0"    
 Feb 03         "3"      "5"      "1"      "0"      "8"    
 Mar 03         "1"      "8"      "9"      "7"      "9"  
 Apr 03         "9"      "6"      "2"      "0"      "2"  
 May 03         "2"      "0"      "5"      "4"      "4" 

所以在这一点上,我的日期是实际的行名而不是​​数据点。我的问题是,有没有简单的解决方法?我可以将行名转换为向量,然后使用 cbind 将其添加为变量吗?

【问题讨论】:

  • reshape2 melt 重复
  • 使用reshape代替转换。
  • 文章标题也可以更好地描述为转置矩阵,而不是宽/长变化
  • 基于第二个重复链接:library(reshape2); recast(df, variable ~ hospital_names, id.var = 'hospital_names')

标签: r transform


【解决方案1】:

欢迎使用 R。使用包(如 cmets 中建议的 Reshape2)是一种方法,但就您在这里所做的水平而言,我可能猜想您想要从基础 R 获得更简单的解决方案。

几点:

  • 通常最好不要将 R 函数名称用作变量名称 (例如testmat &lt;- matrix(...) 而不是matrix &lt;- matrix(...))否则您可能会覆盖函数/变量。

  • “t”表示矩阵运算transpose,而不是变换,它只是交换列和行。

也就是说,我想你想要这样的东西。

matx <- matrix(round(runif(25)*10), nrow = 5, ncol = 5)
hospital_names <- c("Hosp A", "Hosp B", "Hosp C", "Hosp D", "Hosp E")
dates <- c("Jan 03", "Feb 03", "Mar 03", "Apr 03", "May 03")
df2 <- data.frame(dates=dates,t(matx))
colnames(df2) <- c("dates",hospital_names)

其输出为:

   dates Hosp A Hosp B Hosp C Hosp D Hosp E
1 Jan 03      1      7      0      9      7
2 Feb 03      6      5      7      9      8
3 Mar 03     10     10      5      0      9
4 Apr 03      7      2      2      3      4
5 May 03      7      7      2      7      2

发生的事情是将矩阵保留为(数字)矩阵,将名称分开,然后在定义数据框时,将日期作为第一列(命名为“日期”,然后添加矩阵的转置( matx))。最后,通过使用 concatenate 在其他医院名称 c("dates",hospital_names) 前面添加标题“dates”,在正确的位置获取所有正确的名称。

如果您真的希望您的“宽”格式变为“长”格式,那就另当别论了,链接在 cmets 中。

require(reshape2)
melt(df2)

有输出

    dates variable value
1  Jan 03   Hosp A     1
2  Feb 03   Hosp A     6
3  Mar 03   Hosp A    10
4  Apr 03   Hosp A     7
5  May 03   Hosp A     7
6  Jan 03   Hosp B     7
7  Feb 03   Hosp B     5
8  Mar 03   Hosp B    10
9  Apr 03   Hosp B     2
10 May 03   Hosp B     7
11 Jan 03   Hosp C     0
12 Feb 03   Hosp C     7
13 Mar 03   Hosp C     5
14 Apr 03   Hosp C     2
15 May 03   Hosp C     2
16 Jan 03   Hosp D     9
17 Feb 03   Hosp D     9
18 Mar 03   Hosp D     0
19 Apr 03   Hosp D     3
20 May 03   Hosp D     7
21 Jan 03   Hosp E     7
22 Feb 03   Hosp E     8
23 Mar 03   Hosp E     9
24 Apr 03   Hosp E     4
25 May 03   Hosp E     2

【讨论】:

  • 非常感谢 - 这非常有帮助。
  • 我遇到的一个小问题是,对于我的实际数据集,我没有一个名为“日期”的向量(我在本示例中使用它来创建列名)。我只是将列名设置为日期(如果有意义的话)。有没有一种方法可以提取现有的列名并创建一个向量,然后我可以按照您上面描述的方式使用该向量?再次感谢您的帮助。
  • 当然。如果您的矩阵称为“mydata”,则 colnames(mydata) 将是每列名称的字符向量。如果您不需要其他列标题(例如仅获取日期),您可能需要简要查看它以找出哪些是感兴趣的。您可以使用新向量代替示例中的“日期”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
相关资源
最近更新 更多