我的数据有几个重复的列,我想剪切掉重复的列并重新绑定。
我已经在代码中完成了此操作,但是我想知道是否有更有效的方法来完成此操作。
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)
答案 0 :(得分:2)
另一个基本的R选项是使用split.default
并根据列的names
,unlist
和cbind
个单独的列表分割数据框。
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)使用seq
和lapply
do.call(rbind, lapply(seq(1, ncol(df), by = 2), function(i) df[i:(i+1)]))
6)或与split.default
和bind_rows
library(dplyr)
bind_rows(split.default(df, cumsum(names(df) == "a")))
7)或与split.default
和rbindlist
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'