将单行转换为多行,忽略NA

时间:2017-07-27 15:32:12

标签: r

我有以下数据集

ID  COL1    COL2    COL3
1   22      12      NA
2   2       NA      NA
3   1       2       4
4   NA      NA      NA

以上数据需要转换为以下格式

ID  VALUE
1   22
1   12
2   2
3   1
3   2
3   4

请注意,源数据框中存在NA,应在最终表格中忽略。

4 个答案:

答案 0 :(得分:4)

要获得较大数据集的速度,请使用data.table melt方法:

library("data.table")
setDT(df)
melt(df, id.vars = "ID", na.rm = TRUE)
#    ID variable value
# 1:  1     COL1    22
# 2:  2     COL1     2
# 3:  3     COL1     1
# 4:  1     COL2    12
# 5:  3     COL2     2
# 6:  3     COL3     4

答案 1 :(得分:3)

library(dplyr)
library(tidyr)

gather(df, column, value, COL1:COL3, na.rm=TRUE) %>%
  select(-column)

答案 2 :(得分:2)

在基数R中,您可以使用lapply浏览列并提取非NA元素和相应的ID

do.call(rbind, lapply(df[,-1], function(x)
    data.frame(ID = df$ID[!is.na(x)], VALUE = x[!is.na(x)])))
#       ID VALUE
#COL1.1  1    22
#COL1.2  2     2
#COL1.3  3     1
#COL2.1  1    12
#COL2.2  3     2
#COL3    3     4

如有必要,可以在一个附加步骤中更改订单

df2 = do.call(rbind, lapply(df[,-1], function(x)
    data.frame(ID = df$ID[!is.na(x)], VALUE = x[!is.na(x)])))
do.call(rbind, split(df2, df2$ID))
#         ID VALUE
#1.COL1.1  1    22
#1.COL2.1  1    12
#2         2     2
#3.COL1.3  3     1
#3.COL2.2  3     2
#3.COL3    3     4

数据

df = structure(list(ID = 1:4, COL1 = c(22L, 2L, 1L, NA), COL2 = c(12L, 
NA, 2L, NA), COL3 = c(NA, NA, 4L, NA)), .Names = c("ID", "COL1", 
"COL2", "COL3"), class = "data.frame", row.names = c(NA, -4L))

答案 3 :(得分:1)

这是base R选项

d1 <- na.omit(data.frame(ID = rep(df1$ID, each = ncol(df1)-1), VALUE = c(t(df1[-1]))))
d1
#  ID VALUE
#1  1    22
#2  1    12
#4  2     2
#7  3     1
#8  3     2
#9  3     4

或者我们可以使用data.table

的紧凑选项
library(data.table)
setDT(df1)[, unlist(.SD), .(ID)][!is.na(V1)]