【问题标题】:Melt data frame row by row逐行融化数据框
【发布时间】:2016-07-26 08:34:51
【问题描述】:

如何逐行融合数据框? 我在论坛上找到了一个真正的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 循环逐行融化它,然后将它们 rbind 在一起。

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)
}

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

【问题讨论】:

  • 查看 tidyr::gather 但没有融化达到您想要的效果?
  • @chinsoon12 不,melt 将逐列执行,即“值”列将是 20,22,14,75,29,51,12,20 而不是 20,29,12 ,20,22,51,14,75
  • 我发布了一个解决方案。你可以检查一下。

标签: r reshape melt


【解决方案1】:

我们复制数据集的第一列“V1”和names,除了第一列名称以创建预期输出的第一列和第二列,而“值”列是通过转置数据集而不使用第一列。

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)在我们创建一个row id列(add_rownames来自dplyr)然后arrange这些行之后将'wide'转换为'long'格式.

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][]

【讨论】:

  • 谢谢,这正是我要找的。从来没想过这样做,卡在“如何融化一个数据框”
【解决方案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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 2019-03-17
    • 2021-10-27
    • 2018-06-21
    • 1970-01-01
    相关资源
    最近更新 更多