使用下面注释中显示的输入,运行问题中显示的melt,然后将value_1、value_2 和value_3 转换为仅1、2 和3,并添加subseq 列以区分具有相同键的行。删除空的 value 行并使用 dcast 删除 subseq 列转换回宽格式:
library(reshape2)
long <- melt(DF, id.var = "name") # from question
long2 <- transform(long, num = gsub("\\D", "", variable),
subseq = ave(1:nrow(m), name, variable, FUN = seq_along),
variable = NULL)
long3 <- subset(long2, value != "")
wide <- dcast(subseq + num ~ name, data = long3, value.var = "value")[-1]
给予:
> wide
num AK HU KO
1 1 x z b
2 2 X Z B
3 1 y a c
4 2 Y A C
5 1 m f d
6 2 M F D
7 3 B C B
对照预期检查:
identical(wide, expected)
## [1] TRUE
注意
可重现形式的输入是:
Lines <- "
name value_1 value_2 value_3
AK x X
AK y Y
AK m M B
HU z Z
HU a A
HU f F C
KO b B
KO c C
KO d D B"
DF <- read.table(text = Lines, header = TRUE, as.is = TRUE, fill = TRUE, strip.white = TRUE)
我们假设num 是一个因素,而其他数据是字符——我们无法判断其意图是什么,因为输入在问题中没有以可重现的形式给出。
expected <- structure(list(num = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 3L), .Label =
c("1", "2", "3"), class = "factor"), AK = c("x",
"X", "y", "Y", "m", "M", "B"), HU = c("z", "Z", "a", "A", "f",
"F", "C"), KO = c("b", "B", "c", "C", "d", "D", "B")), row.names = c(NA,
-7L), class = "data.frame")
更新 2
此变体使用 0/1 数据和整数 num:
set.seed(123)
# test data
DF2 <- data.frame(name = DF$name,
value_1 = rbinom(9, 1, .5),
value_2 = rbinom(9, 1, .5),
value_3 = ifelse(DF[, 4] == "", NA, rbinom(9, 1, .5)))
long <- melt(DF2, id.var = "name")
long2 <- subset(long, !is.na(value))
long3 <- transform(long2, num = as.integer(gsub("\\D", "", variable)),
subseq = ave(1:nrow(long2), name, variable, FUN = seq_along),
variable = NULL)
wide <- dcast(subseq + num ~ name, data = long3, value.var = "value")[-1]
给予:
> wide
num AK HU KO
1 1 0 1 1
2 2 0 1 1
3 3 1 1 1
4 1 1 1 1
5 2 1 1 0
6 1 0 0 1
7 2 0 0 0