解决方案
我接受了下面@MauritsEvers和@akrun提供的解决方案。
问题
对于一个数据框,我只希望保留每组重复列中的1列。此外,保留的列采用的名称是重复列集中所有列名称的串联。数据框中有多组重复的列。数据帧包含数万列,因此使用for循环可能会花费太多时间。
我尝试了以下方法的组合:使用plicate(),summary(),aggregate(),lapply(),apply()和for循环。
输入数据帧(df_in):
0 1 2 3 4 5 6 7
0 1 0 0 1 0 1 1
0 1 0 1 1 0 0 0
1 0 1 0 0 1 1 0
输出数据帧(df_out):
0-2-5 1-4 3 6 7
0 1 0 1 1
0 1 1 0 0
1 0 0 1 0
答案 0 :(得分:2)
这里是tidyverse
的一个选项。我们将数据gather
转换为“长”格式,将“值”转换为字符串,然后按“值”分组,paste
将“键”列在一起,将“值”的行分开,然后spread
的“值”列以获取预期的输出
library(tidyverse)
gather(df_in) %>%
group_by(key) %>%
summarise(value = toString(value)) %>%
group_by(value) %>%
summarise(key = paste(key, collapse="-")) %>%
separate_rows(value) %>%
group_by(key) %>%
mutate(n = row_number()) %>%
spread(key, value) %>%
select(-n)
# A tibble: 3 x 5
# `0-2-5` `1-4` `3` `6` `7`
# <chr> <chr> <chr> <chr> <chr>
#1 0 1 0 1 1
#2 0 1 1 0 0
#3 1 0 0 1 0
否则,带有tidyverse
的另一个选项就是
t(df_in) %>%
as.data.frame %>%
mutate(grp = group_indices(., V1, V2, V3)) %>%
mutate(rn = row_number() - 1) %>%
group_split(grp, keep = FALSE) %>%
map_dfc(~ .x %>%
mutate(rn = str_c(rn, collapse="-")) %>%
slice(1) %>%
gather(key, val, -rn) %>%
rename(!! .$rn[1] := val) %>%
select(ncol(.)))
# A tibble: 3 x 5
# `0-2-5` `3` `7` `6` `1-4`
# <int> <int> <int> <int> <int>
#1 0 0 1 1 1
#2 0 1 0 0 1
#3 1 0 0 1 0
或者我们也可以使用data.table
方法
library(data.table)
dcast(melt(as.data.table(t(df_in))[, grp := .GRP, .(V1, V2, V3)][,
c(.SD[1], cn = paste(.I-1, collapse="-")) , .(grp)],
id.var = c('cn', 'grp')), variable ~ cn, value.var = 'value')[,
variable := NULL][]
# 0-2-5 1-4 3 6 7
#1: 0 1 0 1 1
#2: 0 1 1 0 0
#3: 1 0 0 1 0
df_in <- structure(list(`0` = c(0L, 0L, 1L), `1` = c(1L, 1L, 0L), `2` = c(0L,
0L, 1L), `3` = c(0L, 1L, 0L), `4` = c(1L, 1L, 0L), `5` = c(0L,
0L, 1L), `6` = c(1L, 0L, 1L), `7` = c(1L, 0L, 0L)),
class = "data.frame", row.names = c(NA, -3L))
答案 1 :(得分:1)
您可以在基本R中执行以下操作
获取相同列的索引
idx <- split(seq_along(names(df)), apply(df, 2, paste, collapse = "_"))
从低到高排序索引
idx <- idx[order(sapply(idx, function(x) x[1]))]
idx
的名称与列名的关联
names(idx) <- sapply(idx, function(x) paste(names(df)[x], collapse = "_"))
创建最终的matrix
sapply(idx, function(x) df[, x[1]])
# col0_col2_col5 col1_col4 col3_col6 col7
#[1,] 0 1 1 1
#[2,] 0 1 0 0
#[3,] 1 0 1 0
请注意,生成的对象是matrix
,因此,如果需要data.frame
,只需强制转换as.data.frame
。
我对示例数据进行了一些更改,以使列名没有数字。
df <- read.table(text =
"col0 col1 col2 col3 col4 col5 col6 col7
0 1 0 1 1 0 1 1
0 1 0 0 1 0 0 0
1 0 1 1 0 1 1 0", header = T)