如何在 R 中 "melt" 按行而不是按列?
How to "melt" row wise instead of column wise in R?
我有一个数据框 A
,我想按行而不是按列融化,看起来像 B
(这也不包括其中包含 NA
的观察结果)。这可以用 "melt" 函数来完成吗?
A <- read.table(text=" Id1 Id2 Var1 Var2 Var3
1 1 1 2 NA
1 2 NA 3 4
1 3 5 6 7 ", header=T)
B <- read.table(text=" Id1 Id2 NewVar
1 1 1
1 1 2
1 2 3
1 2 4
1 3 5
1 3 6
1 3 7 ", header=T)
我找到了一个类似问题的 answer,但该功能似乎有点矫枉过正,超出了我目前的 R 技能。
我们可以 order
在 melt
ing
之后
library(data.table)
melt(setDT(A), id.var = c("Id1", "Id2"), na.rm = TRUE, value.name = "NewVar"
)[order(Id1, Id2)][, variable := NULL][]
# Id1 Id2 NewVar
#1: 1 1 1
#2: 1 1 2
#3: 1 2 3
#4: 1 2 4
#5: 1 3 5
#6: 1 3 6
#7: 1 3 7
或者我们可以通过复制 'A' 的行扩展 'Id' 列来处理 base R
,并且 cbind
转置非 ID 列, 连接起来。
`row.names<-`(na.omit(data.frame(A[rep(1:nrow(A), each =3), 1:2],
NewVar= c(t(A[-(1:2)])))), NULL)
# Id1 Id2 NewVar
#1 1 1 1
#2 1 1 2
#3 1 2 3
#4 1 2 4
#5 1 3 5
#6 1 3 6
#7 1 3 7
来自tidyverse,melt -> summarize -> unnest
library(reshape2)
library(tidyr)
melt(A, id=c("Id1", "Id2")) %>% group_by(Id1, Id2) %>%
summarise(value=list(value[!is.na(value)])) %>% unnest()
# Source: local data frame [7 x 3]
# Groups: Id1 [1]
#
# Id1 Id2 value
# <int> <int> <int>
# 1 1 1 1
# 2 1 1 2
# 3 1 2 3
# 4 1 2 4
# 5 1 3 5
# 6 1 3 6
# 7 1 3 7
编辑
由于 melt
有一个 NA
删除参数(来源:@Frank),一行就可以了。注意:此行是 akrun 的 data.table 方法的 reshape2 版本:
melt(A, id=c("Id1", "Id2"), na.rm=TRUE)[-3]
您可以将 dplyr
与 tidyr
包中的 gather
一起使用:
library(dplyr)
library(tidyr)
A %>% gather(Key,NewVar,Var1:Var3) %>%
filter(!is.na(NewVar)) %>%
arrange(Id1,Id2) %>% select(-Key)
## Id1 Id2 NewVar
##1 1 1 1
##2 1 1 2
##3 1 2 3
##4 1 2 4
##5 1 3 5
##6 1 3 6
##7 1 3 7
这会将 Var1:Var3
列收集到 NewVar
列中的行中。 Key
列将包含收集的列的名称,我们在最终结果中不需要这些名称。收集后,filter
取出 NewVar
中的 NA
行。然后按 ID1
排序,然后按 ID2
排序并删除 Key
列。
我有一个数据框 A
,我想按行而不是按列融化,看起来像 B
(这也不包括其中包含 NA
的观察结果)。这可以用 "melt" 函数来完成吗?
A <- read.table(text=" Id1 Id2 Var1 Var2 Var3
1 1 1 2 NA
1 2 NA 3 4
1 3 5 6 7 ", header=T)
B <- read.table(text=" Id1 Id2 NewVar
1 1 1
1 1 2
1 2 3
1 2 4
1 3 5
1 3 6
1 3 7 ", header=T)
我找到了一个类似问题的 answer,但该功能似乎有点矫枉过正,超出了我目前的 R 技能。
我们可以 order
在 melt
ing
library(data.table)
melt(setDT(A), id.var = c("Id1", "Id2"), na.rm = TRUE, value.name = "NewVar"
)[order(Id1, Id2)][, variable := NULL][]
# Id1 Id2 NewVar
#1: 1 1 1
#2: 1 1 2
#3: 1 2 3
#4: 1 2 4
#5: 1 3 5
#6: 1 3 6
#7: 1 3 7
或者我们可以通过复制 'A' 的行扩展 'Id' 列来处理 base R
,并且 cbind
转置非 ID 列, 连接起来。
`row.names<-`(na.omit(data.frame(A[rep(1:nrow(A), each =3), 1:2],
NewVar= c(t(A[-(1:2)])))), NULL)
# Id1 Id2 NewVar
#1 1 1 1
#2 1 1 2
#3 1 2 3
#4 1 2 4
#5 1 3 5
#6 1 3 6
#7 1 3 7
来自tidyverse,melt -> summarize -> unnest
library(reshape2)
library(tidyr)
melt(A, id=c("Id1", "Id2")) %>% group_by(Id1, Id2) %>%
summarise(value=list(value[!is.na(value)])) %>% unnest()
# Source: local data frame [7 x 3]
# Groups: Id1 [1]
#
# Id1 Id2 value
# <int> <int> <int>
# 1 1 1 1
# 2 1 1 2
# 3 1 2 3
# 4 1 2 4
# 5 1 3 5
# 6 1 3 6
# 7 1 3 7
编辑
由于 melt
有一个 NA
删除参数(来源:@Frank),一行就可以了。注意:此行是 akrun 的 data.table 方法的 reshape2 版本:
melt(A, id=c("Id1", "Id2"), na.rm=TRUE)[-3]
您可以将 dplyr
与 tidyr
包中的 gather
一起使用:
library(dplyr)
library(tidyr)
A %>% gather(Key,NewVar,Var1:Var3) %>%
filter(!is.na(NewVar)) %>%
arrange(Id1,Id2) %>% select(-Key)
## Id1 Id2 NewVar
##1 1 1 1
##2 1 1 2
##3 1 2 3
##4 1 2 4
##5 1 3 5
##6 1 3 6
##7 1 3 7
这会将 Var1:Var3
列收集到 NewVar
列中的行中。 Key
列将包含收集的列的名称,我们在最终结果中不需要这些名称。收集后,filter
取出 NewVar
中的 NA
行。然后按 ID1
排序,然后按 ID2
排序并删除 Key
列。