我有两个看起来像这样的数据框:
>df.A
NAME pvalues index
A 0.9 1
B 0.8 2
C 0.7 3
D 0.6 4
E 0.5 5
F 0.4 6
G 0.3 7
H 0.2 8
I 0.1 9
>df.B
NAME VALUE index
B 100 1
G 99 2
H 98 3
C 97 4
D 96 5
F 95 6
A 94 7
I 93 8
E 92 9
我想多次从df.A
中抽样元素(例如100),每次选择4个元素,然后查看df.B
的哪些索引匹配这些新数据。框架,以及结束这些新data.frames的索引。
我的方法如下;
res = list(data.frame())
for (i in 1:100){
res[[i]] = as.data.frame(sample(df.A$NAME, 4))
names(res[[i]]) <- 'NAME'
}
func <- function(x,y){merge(x, y, by.x=names(x)[1], by.y=names(y)[1])}
rand <- lapply(res, func, df.B)
sum.random = sapply(rand, function(x) sum(x$index))
两个data.frames
都是我的实际数据(13000行和4列)的摘要,因此,流程的速度很重要。我认为,由于merge
步骤,我目前的方法需要很长时间。
我也试过data.table
dt = data.table(df.B, key='NAME')
fn = function(x){dt[x]};
rand2 = lapply(res, func)
但它也是两个慢,
改进代码的任何想法?当然,我错过了一些明显的东西
由于
答案 0 :(得分:2)
也许是这样的:
n.samp <- 4
n <- 100
samp.names <- replicate(n, sample(df.A$NAME, n.samp))
library(data.table)
DT.B <- as.data.table(df.B)
setkey(DT.B, NAME)
tmp <- DT.B[c(samp.names),]
tmp[, grp := rep(seq_len(n), each=n.samp) ]
sum.random <- tmp[,sum(index), by=grp]$V1
你没有说清楚为什么你不能直接采样df.B
。名字不是唯一的吗?如果是这种情况,您可以使用:
samp.names <- data.table(NAME=c(samp.names),
grp = rep(seq_len(n), each=n.samp), key="NAME")
tmp <- DT.B[samp.names, all=TRUE]
tmp[,sum(index, na.rm=TRUE), by=grp]$V1
答案 1 :(得分:0)
尝试这种方法,你可以避免R中的for loop
:(我假设样本量= 3)
Data preparation
mydf1<-list(df1)
mydf1a<-rep(mydf1,100)
mydf2<-list(df2)
mydf2a<-rep(mydf2,100)
sampleno<-as.list(1:100)
抽样
set.seed(1)
kk<-Map(function(x) x[sample(1:nrow(x),3,replace=FALSE),], mydf1a)
ll<-Map(function(x,y,z)cbind(sampleno=z,mysum=sum(x[which(x[,1] %in% y[,1]),3])),kk,mydf2a,sampleno)
myresult<-data.frame(do.call(rbind,ll))
head(myresult)
sampleno mysum
1 1 17
2 2 18
3 3 20
4 4 11
5 5 17
6 6 18