【问题标题】:R - Wide to long format Dataframe, new colnames [duplicate]R - 宽到长格式数据框,新的列名 [重复]
【发布时间】:2019-06-16 17:50:57
【问题描述】:

我需要使用长格式数据框才能在 ggplot 库中使用它。在此图中,我需要将 x= 作为条件 y=count of 0 和 1 并填充 = 0 和 1。根据我发现我需要使用长格式数据框,所以这是我的问题,我自己做不到.

这是我当前的数据框格式:

      C1  C2  C3    
1      0   1   0       
2      1   1   0       
3      1   0   0 

我想把它变成一个新的形状,比如:

id             Conditions Values
1               C1          0
2               C1          1   
3               C1          1 
1               C2          1
2               C2          1
3               C2          0
1               C3          0
2               C3          0
1               C3          0 

我尝试使用 unstack,melt,主要是 reshape 功能和所有这些,但首先没有成功,所以我不确定它是否是我想要实现的正确方法/解决方案。 非常感谢您的帮助。

【问题讨论】:

  • 我在发帖前看到了这个问题,我承认它非常相似,但即使在阅读了几个 reshape 函数教程之后,我也无法在我的情况下编写它。
  • 这绝对是重复的,但无论如何我已经为您的特定数据提供了答案。我认为另一篇帖子中得票最多的答案比接受的答案更有趣。 Jaap 使用多种策略给出了非常透彻的解释。
  • 我可能过于关注 Aniko 的解决方案,也许 reshape 不是我的解决方案?

标签: r dataframe ggplot2


【解决方案1】:

整理

tidyrgather 是最简单、最常用的选项之一。您首先需要将行名称转换为新变量id。我喜欢tibblerownames_to_column,因为我更喜欢描述性很强的函数名称,但你可以使用任何你喜欢的方法:

library(tidyr)
library(tibble)

df %>% 
    rownames_to_column("id") %>%
    gather(conditions, values, -id)

#### OUTPUT ####

  id conditions values
1  1         C1      0
2  2         C1      1
3  3         C1      1
4  1         C2      1
5  2         C2      1
6  3         C2      0
7  1         C3      0
8  2         C3      0
9  3         C3      0

数据后面的第一个参数 (conditions) 告诉 R 将变量名称存储在哪里,第二个参数 (values) 告诉 R 将每个前一个变量的值存储在哪里。 -id 只是告诉 R 收集除 id 之外的所有内容。

基础 R

根据您的要求,并以 Onyambu 的出色建议为基础,以下是您可以如何使用 base R 的 reshape。您可以找到关于如何使用reshapehere 的详细说明。

reshape 使用起来可能有点不直观和麻烦,这是我能想到的最不痛苦的方法。它要求您在长格式数据框中添加您希望值列具有的名称,在本例中为 value。你也应该在里面放一个.,即value.C1。您也可以不执行此步骤,但如果您阅读我上面链接的文章,您会发现使用这种特定的命名约定可以在您处理更复杂的情况时为您节省一些心痛:

names(df) <- paste0("value.", names(df))

reshape(df,                    # data
        direction = "long",    # long or wide
        varying = 1:3,         # the columns that should be stacked
        timevar = "condition"  # name of "time" variable, basically groups
        )

#### OUTPUT ####

     condition value id
1.C1        C1     0  1
2.C1        C1     1  2
3.C1        C1     1  3
1.C2        C2     1  1
2.C2        C2     1  2
3.C2        C2     0  3
1.C3        C3     0  1
2.C3        C3     0  2
3.C3        C3     0  3

显然reshape 会根据行自动创建一个id 变量。如果您的数据框中已经有 id,它也会识别它:

names(df) <- paste0("value.", names(df))
df$id <- letters[1:3] # add an `id` variable

reshape(df,
        direction = "long",
        varying = 1:3,
        timevar = "condition"
        )

#### OUTPUT ####

     id condition value
a.C1  a        C1     0
b.C1  b        C1     1
c.C1  c        C1     1
a.C2  a        C2     1
b.C2  b        C2     1
c.C2  c        C2     0
a.C3  a        C3     0
b.C3  b        C3     0
c.C3  c        C3     0

另一个基本 R 选项(归功于 Onyambu)正在使用 cbindstack。它并不容易推广到更复杂的情况,但通过一些调整绝对是可能的。这应该可以毫无问题地处理您的示例数据(您需要更改一些列名):

cbind(id = 1:nrow(df), stack(df))

#### OUTPUT ####

  id values ind
1  1      0  C1
2  2      1  C1
3  3      1  C1
4  1      1  C2
5  2      1  C2
6  3      0  C2
7  1      0  C3
8  2      0  C3
9  3      0  C3

重塑2

另一个选项是来自reshape2 包的meltmelt 使用起来非常简单,但它已被 gather 取代(它本身将在某些时候被 pivot_long 取代):

library(reshape2)

df$id <- 1:nrow(df) # add id variable
melt(df, id.vars = "id")

#### OUTPUT #### 

  id variable value
1  1       C1     0
2  2       C1     1
3  3       C1     1
4  1       C2     1
5  2       C2     1
6  3       C2     0
7  1       C3     0
8  2       C3     0
9  3       C3     0

【讨论】:

  • 完美运行,非常感谢!当我在努力使用重塑功能时,你知道在我的情况下如何通过正确使用重塑功能来解决它​​吗?我想提高我的技能,很高兴知道如何使用 reshape(),谢谢你的帮助。
  • 您还可以展示基本 R 解决方案,例如 cbind(id=1:3,stack(df)),甚至使用基本 R 重塑,例如 reshape(df,1:3,dir="long",sep="")
  • @C.Brn 抱歉,但我将 reshape 包与 reshape 函数混淆了。我已经通过使用该函数的示例再次编辑了我的答案。一定要看看我链接到的文章以获得更全面的解释。
  • @Onyambu 感谢您的提示。我已经包含了一些关于reshape 函数和cbind 选项的信息,并将你命名为灵感。
  • 完美,我不想再通过询问重塑功能来打扰您。但是现在这个例子一切都清楚了!非常感谢@gersht,也感谢 Onyambu 的提示
【解决方案2】:

如果你只想用reshape你可以试试

df <- read.table(text = "      C1  C2  C3    
1      0   1   0       
2      1   1   0       
3      1   0   0 ")
df$id <- 1:3

library(reshape)

df2 <-melt(df,id="id")
df2
  id variable value
1  1       C1     0
2  2       C1     1
3  3       C1     1
4  1       C2     1
5  2       C2     1
6  3       C2     0
7  1       C3     0
8  2       C3     0
9  3       C3     0

你也可以试试data.tablereshape

df <- read.table(text = "      C1  C2  C3    
1      0   1   0       
2      1   1   0       
3      1   0   0 ")
df$id <- 1:3
library(reshape)
library(data.table)

setDT(df)
df2 <-melt(df,id="id")
 df2[,.(Conditions= paste0(id,",",variable),Values =value)]
   Conditions Values
1:       1,C1      0
2:       2,C1      1
3:       3,C1      1
4:       1,C2      1
5:       2,C2      1
6:       3,C2      0
7:       1,C3      0
8:       2,C3      0
9:       3,C3      0

【讨论】:

  • 我认为粘贴idvariable 的最后一行并不是真正需要的,但问题中有更多错字(我将编辑问题,请考虑编辑答案,并包括如何在熔化后将condition 命名为variable 列)。
  • @PavoDive 确定请继续,然后我将编辑我的答案。
【解决方案3】:

这是使用 dplyr 完成它的一种方法:

df <- read.table(text =
                   "C1  C2  C3 
0   1   0       
1   1   0       
1   0   0",
                 header = TRUE, stringsAsFactors = FALSE)
df%>%
  mutate(row = rownames(.))%>%
  gather(column, value, -row)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2022-10-23
    • 2021-10-23
    相关资源
    最近更新 更多