如何将data.frame的行转换为列?

时间:2014-06-07 02:41:54

标签: r

我有一系列特定于变量的data.frames,如下所示:

变量1:

LOCATION 2014.01  2014.02  2014.03  2014.04
902010   7        -3       14       5

变量2:

LOCATION 2014.01  2014.02  2014.03  2014.04
902010   9        11       6        3

我想转换变换并将它们组合成以下格式。

LOCATION    DATE     VARIABLE1  VARIABLE2
902010      2014.01  7          9
902010      2014.02  -3         11
902010      2014.03  14         6
902010      2014.04  5          3

我认为正确的方法是转换一个data.frame,然后从日期和位置匹配的其他数据中添加数据。

类似听起来问题的答案推荐库reshape2或函数t(),但我很难理解如何在这种情况下使用它们。我也看到了时间序列库动物园的建议。

4 个答案:

答案 0 :(得分:1)

你应该:

  1. 使用melt
  2. 以长格式重塑您的数据
  3. 使用merge
  4. 将data.frames(LOCATION和日期)合并

    这是一个完整的解决方案:     库(reshape2)

    dat1 <- 'LOCATION 2014.01  2014.02  2014.03  2014.04
    902010   7        -3       14       5'
    
    dat2 <- 'LOCATION 2014.01  2014.02  2014.03  2014.04
    902010   9        11       6        3'
    
    ll <- lapply(list(dat1,dat2),function(x){
    dat <- read.table(text=x,header=TRUE)
    melt(dat,id.vars ='LOCATION')
    })
    
    res <- merge(ll[[1]],ll[[2]],by=1:2)
    
    # LOCATION variable value.x value.y
    # 1   902010 X2014.01       7       9
    # 2   902010 X2014.02      -3      11
    # 3   902010 X2014.03      14       6
    # 4   902010 X2014.04       5       3
    

    额外的步骤是将变量列强制转换为有效日期。

    res$variable <- 
    as.Date(paste0(sub('X','',res$variable),'.01'),
            format='%Y.%m.%d')
    

答案 1 :(得分:1)

1)定义merge函数,merge12合并前两个变量和melt函数melt1,它使用第一个变量作为id。然后定义L,一个数据框列表,并像这样运行Reduce

library(reshape2)

merge12 <- function(..., by = 1:2) merge(..., by = by)
melt1 <- function(..., id = 1) melt(..., id = id)

L <- list(DF1, DF2)
Reduce(merge12, lapply(L, melt1))

对于问题中的数据框,这给出了以下内容

  LOCATION variable value.x value.y
1   902010  2014.01       7       9
2   902010  2014.02      -3      11
3   902010  2014.03      14       6
4   902010  2014.04       5       3

注意:这也适用于两个以上的数据框。只需将它们全部放在列表L中。

2)fn $ 在gsubfn中使用fn$允许函数参数表示为公式,我们可以用更紧凑的方式编写上述内容:

library(reshape2)
library(gsubfn)

L <- list(DF1, DF2)
fn$Reduce(~ merge(..., by = 1:2), fn$lapply(L, ~ melt(..., id = 1)))

给出相同的结果。

已添加(2)

答案 2 :(得分:0)

你试过merge()函数吗?

你可能也觉得它很有用! Merge or combine by rownames

答案 3 :(得分:0)

这是使用基本R函数实现目标的一种方法。

> cb <- cbind(var1[1], names(var1)[-1], sapply(list(var1[-1], var2[-1]), t))
> names(cb)[2:4] <- c("DATE", "VAR1", "VAR2") 
> cb
#   LOCATION     DATE VAR1 VAR2
# 1   902010 X2014.01    7    9
# 2   902010 X2014.02   -3   11
# 3   902010 X2014.03   14    6
# 4   902010 X2014.04    5    3

如果您不介意列的顺序不同,可以将其缩短为三列,

> rb <- rbind(var1 = var1, var2 = var2)
> cbind(t(rb[-1]), LOC = var1$LOCATION)
#          var1 var2    LOC
# X2014.01    7    9 902010
# X2014.02   -3   11 902010
# X2014.03   14    6 902010
# X2014.04    5    3 902010