将数据重组为面板格式-跨列提取单元格值

时间:2019-05-17 08:49:35

标签: r data-manipulation

简而言之: 我所拥有的:

  id year1 year2 year3 size1 size2 size3
   1  2000  2007  2009    50    80   100
   2  2002  2004    NA   100   110    NA

我想要什么:

id  y2000   y2001   y2002   y2003   y2004   y2005   y2006   y2007   y2008   y2009
1      50      50      50      50      50      50      50      80      80     100
2      NA      NA     100     100     110     110     110     110     110     110

我需要将数据重组为面板格式,其中有两组列。一组包含随机年份,另一组包含相应的大小。最后,我想获得一个标准表格式,其中包含相应大小的年列。此外,条目后的后续年份应包含以前的值,直到出现“更新”为止。例如:对于id = 1,最终表应在2000年至2006年之间包含值50,然后在2007年获得值80,依此类推。

mydata <- data.frame("id"=c(1,2),  "year1"=c(2000,2002),    "year2"=c(2007,2004),
                     "year3"=c(2009,NA),    "size1"=c(50,100),  "size2"=c(80,110),
                     "size3"=c(100,NA))             


years <- paste("y", 2000:2009, sep="")
mydata[years] <- NA


opy <- c("year1", "year2", "year3")
ops <- c("size1", "size2", "size3")


ifelse (mydata[opy]==substring(names(mydata[years]),first=2,last=5),
        apply(mydata[years], 2, function(x) x <- mydata[ops]), NA) 

我看到这行不通,但是不幸的是我真的无法解决这个问题。没有错误消息-它根本不希望我这样做。

我正在尝试获取此data.frame:

mydatanew <- data.frame("id"=c(1,2),    "y2000"=c(50,NA), "y2001"=c(50,NA),
                        "y2002"=c(50,100),  "y2003"=c(50,100),
                        "y2004"=c(50,110),  "y2005"=c(50,110),
                        "y2006"=c(50,110),  "y2007"=c(80,110),
                        "y2008"=c(80,110),  "y2009"=c(100,110))

1 个答案:

答案 0 :(得分:1)

以下是使用软件包tidyr的解决方案:

library(tidyverse)
mydata %>%
  gather("key", "value", -id, na.rm=T) %>% 
  extract(key, into=c("base_var", "rank"), regex="([a-zA-Z]*)(\\d*)") %>% 
  spread(base_var, value) %>% 
  select(-rank) %>% 
  complete(id, year=full_seq(year, 1)) %>% 
  group_by(id) %>% 
  fill(size) %>% 
  mutate(year=paste0("y", year)) %>% 
  spread(year, size)

为了更好地理解每个步骤的功能,建议您只执行 x 的前几步,方法是将指令限制在第 x 个管道之前的所有内容({{ 1}})