切割列并使用r中的dataframe rbind

时间:2019-06-06 02:48:59

标签: r dplyr

我的数据有几个重复的列,我想剪切掉重复的列并重新绑定。

我已经在代码中完成了此操作,但是我想知道是否有更有效的方法来完成此操作。

df <- data.frame(a = 1:4,
             b = 5:8,
             a.1 = letters[1:4],
             b.1 = letters[5:8],
             a.2 = LETTERS[1:4],
             b.2 = LETTERS[5:8])
names(df)[c(1,3,5)] <- "a"
names(df)[c(2,4,6)] <- 'b'

d1 <- df[,1:2]
d2 <- df[,3:4]
d3 <- df[,5:6]
d <- rbind(d1,d2) %>% rbind(d3)

2 个答案:

答案 0 :(得分:2)

另一个基本的R选项是使用split.default并根据列的namesunlistcbind个单独的列表分割数据框。

do.call(cbind.data.frame, lapply(split.default(df, names(df)), unlist))

#     a b
#a1   1 5
#a2   2 6
#a3   3 7
#a4   4 8
#a.11 a e
#a.12 b f
#a.13 c g
#a.14 d h
#a.21 A E
#a.22 B F
#a.23 C G
#a.24 D H

如果不需要,可以将行名设置为NULL。通过设置stringsAsFactors = FALSE还将字符作为字符而不是因数读取。

答案 1 :(得分:1)

1)一种选择是遍历数据集的unique names,将数据集列作为子集unlist并设置行名到NULL

out <- as.data.frame(sapply(unique(names(df)), 
        function(x) unlist(df[names(df) ==x])))
row.names(out) <- NULL
out
#   a b
#1  1 5
#2  2 6
#3  3 7
#4  4 8
#5  a e
#6  b f
#7  c g
#8  d h
#9  A E
#10 B F
#11 C G
#12 D H

2)或另一种选择是通过选择备用列来创建data.frame

data.frame(a = unlist(df[c(TRUE, FALSE)]), b = unlist(df[c(FALSE, TRUE)]))

3)unlist数据,根据名称创建逻辑条件,然后对向量进行子集以创建data.frame

v1 <- unlist(df)
i1 <- grepl("a", names(v1))
data.frame(a = v1[i1], b = v1[!i1])

4a)或使用split.default

do.call(rbind, split.default(df, cumsum(names(df) == "a")))

4b)使用%%

do.call(rbind, split.default(df, cumsum(seq_along(df) %% 2)))

5)使用seqlapply

do.call(rbind, lapply(seq(1, ncol(df), by = 2), function(i) df[i:(i+1)]))

6)或与split.defaultbind_rows

library(dplyr)
bind_rows(split.default(df, cumsum(names(df) == "a")))

7)或与split.defaultrbindlist

library(data.table)
rbindlist(split.default(df, cumsum(names(df) == "a")))

8)或另一个选择是melt中的data.table

library(data.table)
melt(setDT(df), measure = patterns("a", "b"), 
   value.name = c("a", "b"))[, variable := NULL][]

注意:确保使用stringsAsFactors = FALSE

创建数据集

数据

df <- data.frame(a = 1:4,
             b = 5:8,
             a.1 = letters[1:4],
             b.1 = letters[5:8],
             a.2 = LETTERS[1:4],
             b.2 = LETTERS[5:8], stringsAsFactors = FALSE)
names(df)[c(1,3,5)] <- "a"
names(df)[c(2,4,6)] <- 'b'