在 R 中按行绑定数据帧的多列的最佳方法
Best way to bind several columns of a dataframe by row in R
我有一个具有以下形式的数据框
ID1 | VALUE |ID2 | VALUE | ID3 | VALUE
111 | one |333 | three | 555 | five
222 | two | | NA | 666 | six
请注意,每列中 values/rows 的数量各不相同(NAs/empty 个值)。
我希望结果如下所示:
ID | VALUE
111 | one
222 | two
333 | three
555 | five
666 | six
我尝试了以下方法:
x = as.matrix(df)
x= matrix(x,ncol = 2)
此过程混合了某些列的 ID 和 VALUE。我的猜测是这是因为 NA 和 NULL 值。
ID | VALUE
111 | one
222 | two
333 | three
five| 555
six | 666
你能为我的问题提出一个快速的解决方案吗?
优雅的解决方案
感谢 nongkrong and akrun 的回答。
我不知道速度如何,但完成工作的最优雅的解决方案如下:
my_final = data.frame(VALUE=unlist(my_data[c(TRUE,FALSE)]), ID=unlist(my_data[c(FALSE, TRUE)]))
my_final = setNames(data.frame(lapply(split(as.list(my_data), c(F, T)), unlist)), c("VALUE", "ID"))
还要省略空行:
my_final_trimmed = my_final[complete.cases(my_final), ]
一个选项是使用 data.table
的开发版本中的 melt
。安装开发版本的说明是 here
.
我们将 'data.frame' 转换为 'data.table' (setDT(df1)
)。使用 melt
,我们将 measure
参数指定为 regex
patterns
以 'ID' 和 'VALUE' 开头的列名。可选参数包括命名 'value' 列,即 value.name
并使用 na.rm=TRUE
删除 NA
值。如果我们不需要 'variable' 列,可以将其分配 (:=
) 为 NULL。
library(data.table)#v1.9.5+
melt(setDT(df1), measure= patterns("^ID", "^VALUE"),
value.name= c("ID", "VALUE"), na.rm=TRUE)[,variable:=NULL][]
# ID VALUE
#1: 111 one
#2: 222 two
#3: 333 three
#4: 555 five
#5: 666 six
数据
df1 <- structure(list(ID1 = c(111L, 222L), VALUE = c("one", "two"),
ID2 = c(333L, NA), VALUE.1 = c("three", NA), ID3 = c(555L,
666L), VALUE.2 = c("five", "six")), .Names = c("ID1", "VALUE",
"ID2", "VALUE.1", "ID3", "VALUE.2"), class = "data.frame",
row.names = c(NA, -2L))
抱歉,如果这个答案对你的情况来说太具体了,但是采用那种形式的数据框,答案是平易近人的(不优雅的)如下:
1) 消灭列名
colnames(dataframe_name) <- NULL
2) 通过子集拆分成更小的数据帧
df1 <- dataframe_name[, 1:2] # columns 1-2
df2 <- dataframe_name[, 3:4] # columns 3-4
df3 <- dataframe_name[, 5:6] # columns 5-6
3) 将列名添加到数据框中
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
4) 将数据框绑定在一起
do.call(rbind, list_of_frames) # call rbind (row bind) on each frame
另一个基数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
我有一个具有以下形式的数据框
ID1 | VALUE |ID2 | VALUE | ID3 | VALUE
111 | one |333 | three | 555 | five
222 | two | | NA | 666 | six
请注意,每列中 values/rows 的数量各不相同(NAs/empty 个值)。
我希望结果如下所示:
ID | VALUE
111 | one
222 | two
333 | three
555 | five
666 | six
我尝试了以下方法:
x = as.matrix(df)
x= matrix(x,ncol = 2)
此过程混合了某些列的 ID 和 VALUE。我的猜测是这是因为 NA 和 NULL 值。
ID | VALUE
111 | one
222 | two
333 | three
five| 555
six | 666
你能为我的问题提出一个快速的解决方案吗?
优雅的解决方案
感谢 nongkrong and akrun 的回答。 我不知道速度如何,但完成工作的最优雅的解决方案如下:
my_final = data.frame(VALUE=unlist(my_data[c(TRUE,FALSE)]), ID=unlist(my_data[c(FALSE, TRUE)]))
my_final = setNames(data.frame(lapply(split(as.list(my_data), c(F, T)), unlist)), c("VALUE", "ID"))
还要省略空行:
my_final_trimmed = my_final[complete.cases(my_final), ]
一个选项是使用 data.table
的开发版本中的 melt
。安装开发版本的说明是 here
.
我们将 'data.frame' 转换为 'data.table' (setDT(df1)
)。使用 melt
,我们将 measure
参数指定为 regex
patterns
以 'ID' 和 'VALUE' 开头的列名。可选参数包括命名 'value' 列,即 value.name
并使用 na.rm=TRUE
删除 NA
值。如果我们不需要 'variable' 列,可以将其分配 (:=
) 为 NULL。
library(data.table)#v1.9.5+
melt(setDT(df1), measure= patterns("^ID", "^VALUE"),
value.name= c("ID", "VALUE"), na.rm=TRUE)[,variable:=NULL][]
# ID VALUE
#1: 111 one
#2: 222 two
#3: 333 three
#4: 555 five
#5: 666 six
数据
df1 <- structure(list(ID1 = c(111L, 222L), VALUE = c("one", "two"),
ID2 = c(333L, NA), VALUE.1 = c("three", NA), ID3 = c(555L,
666L), VALUE.2 = c("five", "six")), .Names = c("ID1", "VALUE",
"ID2", "VALUE.1", "ID3", "VALUE.2"), class = "data.frame",
row.names = c(NA, -2L))
抱歉,如果这个答案对你的情况来说太具体了,但是采用那种形式的数据框,答案是平易近人的(不优雅的)如下:
1) 消灭列名
colnames(dataframe_name) <- NULL
2) 通过子集拆分成更小的数据帧
df1 <- dataframe_name[, 1:2] # columns 1-2
df2 <- dataframe_name[, 3:4] # columns 3-4
df3 <- dataframe_name[, 5:6] # columns 5-6
3) 将列名添加到数据框中
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
4) 将数据框绑定在一起
do.call(rbind, list_of_frames) # call rbind (row bind) on each frame
另一个基数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