整理
tidyr 的gather 是最简单、最常用的选项之一。您首先需要将行名称转换为新变量id。我喜欢tibble 的rownames_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)正在使用 cbind 和 stack。它并不容易推广到更复杂的情况,但通过一些调整绝对是可能的。这应该可以毫无问题地处理您的示例数据(您需要更改一些列名):
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 包的melt。 melt 使用起来非常简单,但它已被 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