逐行熔化数据框

时间:2016-04-06 05:57:55

标签: r reshape melt

如何逐行融合数据框? 我在论坛上找到了一个真正的similar question,但如果没有不同的id变量,我仍然无法解决我的问题。

这是我的数据集:

V1 V2 V3 V4 V5
51 20 29 12 20
51 22 51 NA NA
51 14 NA NA NA
51 75 NA NA NA

我想将其融入:

V1 variable value    
51 V2 20
51 V3 29
51 V4 12
51 V5 20
51 V2 22
51 V3 51
51 V2 14
51 V2 75

目前,我的方法是使用for循环逐行融合,然后将它们组合在一起。

library(reshape)

df <- read.table(text = "V1 V2 V3 V4 V5 51 20 29 12 20 51 22 51 NA NA 51 
+14 NA NA NA 51 75 NA NA NA", header = TRUE)

dfall<-NULL
for (i in 1:NROW(df))
{
  dfmelt<-melt(df,id="V1",na.rm=TRUE)
  dfall<-rbind(dfall,dfmelt)
}

只是想知道是否有更快的方法可以做到这一点?谢谢!

2 个答案:

答案 0 :(得分:2)

我们复制第一列&#34; V1&#34;以及除第一列名称之外的数据集names以创建预期输出的第一列和第二列,而“&#39;值”#39;通过在没有第一列的情况下转置数据集来创建列。

na.omit(data.frame(V1=df1[1][col(df1[-1])],
             variable = names(df1)[-1][row(df1[-1])],
              value = c(t(df1[-1]))))
#   V1 variable value
#1  51       V2    20
#2  51       V3    29
#3  51       V4    12
#4  51       V5    20
#5  51       V2    22
#6  51       V3    51
#9  51       V2    14
#13 51       V2    75

注意:不使用其他包。

或者,我们可以使用gather(来自tidyr)转换广泛的&#39;长期&#39;在我们创建行id列(add_rownames之后的dplyr)然后arrange行之后的格式。

library(dplyr)
library(tidyr)
add_rownames(df1) %>% 
        gather(variable, value, V2:V5, na.rm=TRUE) %>% 
        arrange(rowname, V1) %>% 
        select(-rowname)
#      V1 variable value
#    (int)    (chr) (int)
#1    51       V2    20
#2    51       V3    29
#3    51       V4    12
#4    51       V5    20
#5    51       V2    22
#6    51       V3    51
#7    51       V2    14
#8    51       V2    75

data.table

library(data.table)
melt(setDT(df1, keep.rownames=TRUE),
      id.var= c("rn", "V1"), na.rm=TRUE)[
      order(rn, V1)][, rn:= NULL][]

答案 1 :(得分:2)

您可以为每行创建一个具有唯一ID的列,以便您可以在融化后对其进行排序。使用dplyr

library(reshape2)
library(dplyr)
df %>% mutate(id = seq_len(n())) %>% 
    melt(id.var = c('V1','id'), na.rm = T) %>% 
    arrange(V1, id, variable) %>% 
    select(-id)
#   V1 variable value
# 1 51       V2    20
# 2 51       V3    29
# 3 51       V4    12
# 4 51       V5    20
# 5 51       V2    22
# 6 51       V3    51
# 7 51       V2    14
# 8 51       V2    75

...或基地R:

library(reshape2)
df$id <- seq_along(df$V1)
df2 <- melt(df, id.var = c('V1', 'id'), na.rm = TRUE)
df2[order(df2$V1, df2$id, df2$variable),-2]