[英]Combine data frames picking only columns sharing same name beginnings across data frames
我有这两个数据框,我想用它来创建另一个数据框:
df<-as.data.frame(matrix(rexp(200, rate=.1), ncol=10))
colnames(df)<-c("one","two","three","four","five","six","seven","eight","nine","ten")
df
df.new<-as.data.frame(matrix(rexp(155, rate=.1), ncol=8))
colnames(df.new)<-c("one.two","one.two.new","three.two","three.two.new","five.one","five.one.new","seven.two","seven.two.new")
df.new
我的想法是拥有一个包含这些列的数据框:
(one|one.two|one.two.new|three|three.two|three.two.new|five|five.one|five.one.new)
我可以手动完成,但我的数据框比这些大得多。
用 dplyr 包可以做到这一点吗??
这是另一个较短的替代方案。 我只是不喜欢宽桌子……所以无论如何你必须在某个时候把它融化。
to.pick <- unique(unlist(sapply(colnames(df.new), function(x) {
Reduce(function(a,b) paste(a, b, sep="."), strsplit(x, '.', fixed=TRUE)[[1]], accumulate=TRUE)
})))
zz <- cbind(df, df.new)
out <- subset(zz, select=to.pick)
colnames(out)
[1] "one" "one.two" "one.two.new" "three" "three.two" "three.two.new" "five"
[8] "five.one" "five.one.new" "seven" "seven.two" "seven.two.new"
原答案
对按列名称部分过滤的数据使用熔化/铸造。
library(tidyr)
将东西传播到“正常”的长表示中
df$idx <- 1:nrow(df)
gdf <- gather(df, key, value, -idx)
df.new$idx <- 1:nrow(df.new)
gdf.new <- gather(df.new, key, value, -idx)
获得独特的第一部分
uu <- unique(gdf.new$key)
to.pick <- sapply(uu, function(x) {
strsplit(x, '.', fixed=TRUE)[[1]][1]
})
仅对我们想要的第一个数据帧中的那些进行子集。
gdf.ss <- subset(gdf, key %in% to.pick)
合并仍为“正常”长格式的数据。
out <- rbind(gdf.ss, gdf.new)
扔进“丑陋”的宽幅面
out.wide <- spread(out, key, value)
colnames(out.wide)
[1] "idx" "five" "five.one"
[4] "five.one.new" "one" "one.two"
[7] "one.two.new" "seven" "seven.two"
[10] "seven.two.new" "three" "three.two"
[13] "three.two.new"
如果您坚持按不严格按字母顺序排列的列,我会更新我的答案。
列聚集成三个,让 N= 是集群的数量。
N=3 # for the example provided
foo=seq(1,2*N+1,2)
dplyr::bind_cols(df, df.new) %>% dplyr::select(names(.)[c(foo,
foo+10, foo+11)])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.