在R中按行绑定数据帧的多个列的最佳方法

在R中按行绑定数据帧的多个列的最佳方法,r,data-manipulation,R,Data Manipulation,我有一个dataframe,它的形式如下 ID1 | VALUE |ID2 | VALUE | ID3 | VALUE 111 | one |333 | three | 555 | five 222 | two | | NA | 666 | six 请注意,每列中的值/行数不同(NAs/空值) 我希望结果如下所示: ID | VALUE 111 | one 222 | two 333 | three 555 | five 666 | six 我尝试了以下方法: x

我有一个dataframe,它的形式如下

ID1 | VALUE |ID2 | VALUE | ID3 | VALUE
111  | one   |333 | three | 555 | five
222  | two   |    | NA    | 666 | six
请注意,每列中的值/行数不同(NAs/空值)

我希望结果如下所示:

ID  | VALUE 
111 | one
222 | two
333 | three
555 | five
666 | six
我尝试了以下方法:

x = as.matrix(df)
x= matrix(x,ncol = 2)
此过程混合了某些列的ID和值。我猜这是因为NA和NULL值

ID  | VALUE 
111 | one
222 | two
333 | three
five| 555
six | 666
你能为我的问题提出一个快速的解决方案吗

优雅的解决方案

感谢和的回答。 我不知道速度,但完成这项工作的最优雅的解决方案如下:

x = as.matrix(df)
x= matrix(x,ncol = 2)
  • my_final=data.frame(VALUE=unlist(my_data[c(TRUE,FALSE)]),ID=unlist(my_data[c(FALSE,TRUE)])
  • my_final=setNames(data.frame(lappy(拆分(as.list(my_数据)),c(F,T)),unlist)),c(“VALUE”,“ID”)
还要省略空行,请执行以下操作:

  • my_final\u trimmed=my_final[完成.案例(my_final)]

一个选项是使用
数据表的devel版本中的
melt
。安装devel版本的说明如下

我们将“data.frame”转换为“data.table”(
setDT(df1)
)。使用
melt
,我们使用以“ID”和“VALUE”开头的列名的
regex
模式指定
measure
参数。可选参数包括命名“值”列,即
value.name
和使用
NA.rm=TRUE
删除
NA
值。如果我们不需要“variable”列,可以将它(
:=
)赋值为NULL

数据
df1很抱歉,如果这个答案对您的案例过于具体,但是以这种形式的数据框为例,答案是可接近的(不雅观的),如下所示:

1) 删除列名

colnames(dataframe_name) <- NULL

另一个基数R,使用
split
分隔交替列

res <- setNames(
    data.frame(lapply(split(as.list(dat), c(F, T)), unlist))
  , c("VALUE", "ID"))

res[complete.cases(res), ]
#      VALUE      ID
# ID11   111  one   
# ID12   222  two   
# ID21   333  three 
# ID31   555    five
# ID32   666     six

res这是使用
split
的一个不错的选项。我在考虑data.frame(VALUE=unlist(df1[c(TRUE,FALSE)]),ID=unlist(df1[c(FALSE,TRUE)])
@akrun nice!我也有类似的想法,但我现在只关心
split
,它在我的数据帧(超过500000行)上运行得非常好。谢谢!
df1 <- dataframe_name[, 1:2]  # columns 1-2
df2 <- dataframe_name[, 3:4]  # columns 3-4
df3 <- dataframe_name[, 5:6]  # columns 5-6
f <- function(df) {
    colnames(df) <- c('ID', 'VALUE')  # set colnames for df with 2 cols
    return(df)
} # function to apply to each df

l <- list(df1, df2, df3)
list_of_frames <- lapply(l, f)  # apply colname function to each
do.call(rbind, list_of_frames)  # call rbind (row bind) on each frame
res <- setNames(
    data.frame(lapply(split(as.list(dat), c(F, T)), unlist))
  , c("VALUE", "ID"))

res[complete.cases(res), ]
#      VALUE      ID
# ID11   111  one   
# ID12   222  two   
# ID21   333  three 
# ID31   555    five
# ID32   666     six