2016-01-07 23 views
1

以下是我的数据的矩阵选择特定行的特定数量,如何简单地在中的R

num<- c(6,8,7,5,9,6,7) 
x<- matrix(c(rep(1:7,num),rnorm(sum(num))), nrow=sum(num), ncol=2) 
colnames(x)<-c("subject","value") 

X
受试者值
[1,] 1 0.35182560
[2,1] 1 0.35933614
[3,] 1 -0.89029320
[4,] 1 -0.79991981
[5,1] 1 1.10773640
[6,1] 1 -1.73900484
[7,] 2 1.06632139
[8,] 2 0.71727759
[9,] 2 0.51002247
[10,] 2 1.36132224
[11,] 2 -0.85432175
[12,] 2 -0.49878742
[13,] 2 1.43705322
[14,] 2 0.34052593
[15,] 3 -0.43245360
[16,] 3 1.01687525
[17,] 3 0.48998138
[18,] 3 -1.06197379
[19,] 3 -0.19777785
[20,] 3 1.24940714
[21,] 3 0.47521229
[22] 4 -0.99888249
[23] 4 -0.12678874
[24,] 4 -1.14620801
[25] 4 - 1.29165060
[26] 4 1.56110270
[27,] 5 0.82543156
[28,] 5 -0.61718617
[29,] 5 0.22357131
[30,] 5 0.59639380
[31,] 5 2.72122980
[32,] 5 0.58674354
[33,] 5 0.23674196
[34,] 5 0.78656422
[35,] 5 0.10426860
[36,] 6 0.93059568
[37,] 6 0.16065327
[38,] 6 -2.23496916
[39,] 6 -1.75680495
[40,] 6 0.49717967
[41,] 6 1.13033910
[42] 7 0.71402667
[43] 7 -0.06120018
[44,] 7 -0.67636605
[45,] 7 0.46402913
[46,] 7 -0.99090058
[47,] 7 1.58853435
[48,] 7 -1.15982415

我的任务是在每一个主题来选择数据的特定数目以重新形成新的矩阵。
每个受试者的具体数目是

b<- ceiling(num*0.5) 

b
[1] 3 4 4 3 5 3 4

也就是说,我需要提取
前3行的主体1
前4行的主体2
前4行su对象3,
...
前4行的主题7,
形成一个新的矩阵。

下面是我自己的编码:

b<- ceiling(a*0.5) 
newx<- matrix(0, nrow=sum(b), ncol=2) 
newx<- do.call(rbind, sapply(1:7, function(i){head(x[x[,1]==i,], b[i])})) 

它的工作原理,但它需要时间,有没有更简单的方法来找出这个问题?

下一页末
受试者值
[1,] 1 0.35182560
[2,1] 1 0.35933614
[3,] 1 -0.89029320
[4,] 2 1.06632139
[5,1] 2 0.71727759
[6,] 2 0.51002247
[7,] 2 1.36132224
[8,] 3 -0.43245360
[9,] 3 1.01687525
[10,] 3 0 0.48998138
[11,] 3 -1.06197379
[12,] 4 -0.99888249
[13,] 4 -0.12678874
[14,] 4 -1.14620801
[15,] 5 0.82543156
[16 ,] 5 -0.61718617
[17,] 5 0.22357131
[18,] 5 0.59639380
[19,] 5 2.72122980
[20,] 6 0.93059568
[21] 6 0.16065327
[22, ] 6 -2.23496916
[23,] 7 0.71402 667
[24,] 7 -0.06120018
[25,] 7 -0.67636605
[26,] 7 0。46402913

+0

在b的计算中,'a'是什么? – Gopala

+0

对不起,“a”是num <-c(6,8,7,5,9,6,7),我修改了它,谢谢! – lightsnail

+0

我以为是。我在下面回答。 – Gopala

回答

2

在基础R(假设x是有序第一列):

x[rep(match(unique(x[,1]),x[,1]),b)+sequence(b)-1,] 
+1

从这个简洁而有效的编码中学到了很多东西。十分感谢! – lightsnail

+1

我测试了5,005,000行数据,这个编码是最快的! – lightsnail

0

如果您想保留“半壁江山”为每个主题类型的行,这里是dplyr包做这件事:

library(dplyr) 
num<- c(6,8,7,5,9,6,7) 
df <- as.data.frame(matrix(c(rep(1:7,num),rnorm(sum(num))), nrow=sum(num), ncol=2)) 
df %>% group_by(subject) %>% slice(1:(n()/2)) 
+0

太棒了!非常感谢你!但如果具体数字不规则,我们该怎么办?例如,b <-c(2,1,3,1,2,3,1) – lightsnail

+0

它正在四舍五入。否则,你可以在(n()/ 2)周围明确地使用'floor'或'ceiling',具体取决于你想要的。 – Gopala

3

我们以“主题”栏split在“X”行的序列来创建list,使用Map得到01通过将n指定为'b'(使用listvector的相应元素),unlist并且将'x'的行子集指定为每个list元素的。

x[unlist(Map(head, split(seq_len(nrow(x)), x[,1]), b)),] 

另一种选择是使用data.table。我们将'x'转换为'data.table',用'b'创建第二个data.table,将key列设置为'主题',同时加入.EACHI并获得.SDhead

library(data.table) 
d1 <- as.data.table(x) 
d2 <- data.table(subject=seq_along(b), b) 
setkey(d1, subject) 
sekey(d2, subject) 
d1[d2, head(.SD,b) , by = .EACHI] 
+1

谢谢你,akrun,我从你的编码中获得了“地图”,非常感谢! – lightsnail