索引数据框,创建两个带有样本的列表并进行比较

时间:2013-09-21 12:20:40

标签: r dataframe

我有两个看起来像这样的数据框:

>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)

但它也是两个慢,

改进代码的任何想法?当然,我错过了一些明显的东西

由于

2 个答案:

答案 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