R使用对象作为输入,从长到长重新整形

时间:2016-08-18 20:36:14

标签: r reshape

我有一个宽格式的数据框列表,第1列中有因子变量,第2列中有年化数据。我想绘制这些数据。这样做需要将它们重新整形为长格式。以下是一个数据框的示例:

import akka.http.scaladsl.model.headers._

val responseFuture: Future[HttpResponse] = Http(context.system).singleRequest(HttpRequest(uri = "http://localhost:8080"))

responseFuture.onComplete(response => {
  val cookies = response.get.headers.collect {
    case c: `Set-Cookie` => c.cookie
  }
  println(cookies)
})

我通常使用# SAMPLE DATA x <- structure(list(State = structure(1:3, .Label = c("Alabama", "Alaska", "Arizona", "Arkansas"), class = "factor"), Green.And.Blue.Score.2001 = c(0L, 40L, 65L), Green.And.Blue.Score.2002 = c(20L, 5L, 60L), Green.And.Blue.Score.2003 = c(35L, 15L, 30L)), .Names = c("State", "Green.And.Blue.Score.2001", "Green.And.Blue.Score.2002", "Green.And.Blue.Score.2003"), row.names = c(NA, 3L), class = "data.frame") x # State Green.And.Blue.Score.2001 Green.And.Blue.Score.2002 Green.And.Blue.Score.2003 #1 Alabama 0 20 35 #2 Alaska 40 5 15 #3 Arizona 65 60 30 执行此操作。例如,这很好用:

reshape()

但是,我不想手动为数十个数据框输入# RESHAPE WIDE TO LONG (MANUALLY) y <- reshape(x, idvar = 'State', varying = c('Green.And.Blue.Score.2001', 'Green.And.Blue.Score.2002', 'Green.And.Blue.Score.2003'), v.names = 'Green.And.Blue.Score.', times = c('2001', '2002', '2003'), direction = 'long') y # State time Green.And.Blue.Score. # Alabama 2001 0 # Alaska 2001 40 # Arizona 2001 65 # Alabama 2002 20 # Alaska 2002 5 # Arizona 2002 60 # Alabama 2003 35 # Alaska 2003 15 # Arizona 2003 30 idvarvaryingv.name变量由于某些列名称非常冗长且复杂,并且从数据框到数据框的差异很大,因此简单的times命令无法自动解析它们。我的想法是创建一个函数来从数据框中获取这些输入,其前身如下:

reshape()

每个输出都匹配上面# RESHAPE WIDE TO LONG (FUNCTIONALIZED) id <- noquote(paste("'", names(x[1]), "'", sep = "")) va <- noquote(paste("c('", paste(names(x)[2:length(x)], collapse = "', '"), "')", sep = "")) vn <- noquote(paste("'", sub("(\\..*)$", ".", names(x)[2]) , "'", sep = "")) ti <- noquote(paste("c('", paste(sub(".*(\\d{4})$", "\\1", names(x[2:length(x)])), collapse = "', '"), "')", sep = "")) 的{​​{1}},idvarvaryingv.name输入:

times

但是,当我尝试在#RESHAPE WIDE TO LONG (MANUALLY)函数中使用这些对象时,我收到一条错误消息:

id
# 'State'
va
# c(''Green.And.Blue.Score.2001', ''Green.And.Blue.Score.2002', ''Green.And.Blue.Score.2003')
vn
# ''Green.And.Blue.Score.'
ti
# c('2001', '2002', '2003')
  

[.data.frame(数据,变化[[i]] [1L])出错:未定义   选择的列

我确定我的解决方案是“功能化”&#39; reshape()并不理想。我应该做什么呢?

1 个答案:

答案 0 :(得分:2)

在从名称中提取的材料周围放置引号的努力导致了错误。这是该代码的简化。请注意,我删除了v.names和时间,因为当列名称被“。”正确分隔时,这些是自动计算的。

y <- reshape(x, 
     idvar = names(x)[1],
   varying = names(x)[-1],

 direction = 'long')
 y
#-----    
           State time Score
Alabama.2001 Alabama 2001     0
Alaska.2001   Alaska 2001    40
Arizona.2001 Arizona 2001    65
Alabama.2002 Alabama 2002    20
Alaska.2002   Alaska 2002     5
Arizona.2002 Arizona 2002    60
Alabama.2003 Alabama 2003    35
Alaska.2003   Alaska 2003    15
Arizona.2003 Arizona 2003    30

如果我们在你的新例子中使用它,我们可以在“.S”处获得“分裂”,从而得到合理的结果。第一个句点和“拆分”模式之间的列名文本将移动到列名称,而领先的州名称和年份一起作为rowname加入:

 y <- reshape(x, 
      idvar = names(x)[1],
    varying = names(x)[-1],
    split = list(regexp = "\\.S", include = TRUE),
  direction = 'long')
  y

                     State       time Green.And.Blue.
Alabama.Score.2001 Alabama Score.2001               0
Alaska.Score.2001   Alaska Score.2001              40
Arizona.Score.2001 Arizona Score.2001              65
Alabama.Score.2002 Alabama Score.2002              20
Alaska.Score.2002   Alaska Score.2002               5
Arizona.Score.2002 Arizona Score.2002              60
Alabama.Score.2003 Alabama Score.2003              35
Alaska.Score.2003   Alaska Score.2003              15
Arizona.Score.2003 Arizona Score.2003              30