2017-07-27 79 views
1

我有以下數據集轉換單排多列,忽略的NA

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是本在源數據框中應該在決賽桌中被忽略。

+0

使用'tidyr :: gather' –

+0

'reshape2 ::融化(DF,ID =「ID」,na.rm = TRUE)'你幾乎可以在那裏找到你。 (您需要安裝reshape2軟件包。) – Frank

+2

@ Jaap在鏈接問答中的回答涵蓋了各種函數的'na.rm ='參數(融入reshape2,熔化data.table,融入tidyr)。如果你不想安裝一個新的軟件包,可以從'base或@db'中找到'subset(cbind(DF [1],v = unlist(DF [-1])),!is.na(v))'下面的答案。 – Frank

回答

3
library(dplyr) 
library(tidyr) 

gather(df, column, value, COL1:COL3, na.rm=TRUE) %>% 
    select(-column) 
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 

DATA

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)) 
4

對於速度具有較大的數據集,可使用data.tablemelt方法:

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

這裏是一個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)]