2013-08-30 72 views
44

我有一个包含10列的数据框,收集“用户”的操作,其中一列包含一个ID(不唯一,标识用户) (第10栏)。数据帧的长度约为750000行。我试图提取单个数据框(以获取数据框的列表或向量),以包含“用户”标识符的列进行分割,以隔离单个参与者的行为。根据列中的公共值将一个大数据帧拆分为数据框列表

ID | Data1 | Data2 | ... | UserID 
1 | aaa | bbb | ... | u_001 
2 | aab | bb2 | ... | u_001 
3 | aac | bb3 | ... | u_001 
4 | aad | bb4 | ... | u_002 

上的一个小样品所得到

list(
ID | Data1 | Data2 | ... | UserID 
1 | aaa | bbb | ... | u_001 
2 | aab | bb2 | ... | u_001 
3 | aac | bb3 | ... | u_001 
, 
4 | aad | bb4 | ... | u_002 
...) 

以下工作得非常好,我(1000行):

paths = by(smallsampleMat, smallsampleMat[,"userID"], function(x) x) 

,然后访问由路径我想要的元素[1 ] 例如。当我应用于原始大型数据框甚至是矩阵表示时,这会扼杀我的机器(4GB RAM,MacOSX 10.6,R 2.15),并且永远不会完成(我知道存在更新的R版本,但我相信这是不是主要问题)。

似乎分裂是更高性能,并在很长时间后完成,但我不知道(劣R知识)如何将得到的向量列表分割成矩阵向量。

path = split(smallsampleMat, smallsampleMat[,10]) 

我也考虑过使用也等big.matrix,但不是很成功,将加快这一进程。

回答

50

您可以轻松地访问列表中的每个元素,例如, path[[1]]。您不能将一组矩阵放入原子向量并访问每个元素。矩阵是具有维度属性的原子向量。我将使用由split返回的列表结构,这是它的设计目的。每个列表元素可以保存不同类型和大小的数据,因此非常灵活,您可以使用*apply函数进一步操作列表中的每个元素。下面的例子。

# For reproducibile data 
set.seed(1) 

# Make some data 
userid <- rep(1:2,times=4) 
data1 <- replicate(8 , paste(sample(letters , 3) , collapse = "")) 
data2 <- sample(10,8) 
df <- data.frame(userid , data1 , data2) 

# Split on userid 
out <- split(df , f = df$userid) 
#$`1` 
# userid data1 data2 
#1  1 gjn  3 
#3  1 yqp  1 
#5  1 rjs  6 
#7  1 jtw  5 

#$`2` 
# userid data1 data2 
#2  2 xfv  4 
#4  2 bfe 10 
#6  2 mrx  2 
#8  2 fqd  9 

访问使用[[运营商这样的每一个元素:

out[[1]] 
# userid data1 data2 
#1  1 gjn  3 
#3  1 yqp  1 
#5  1 rjs  6 
#7  1 jtw  5 

或者使用*apply功能做每个列表元素上的进一步操作。例如,采取data2列的意思是你可以sapply使用这样的:

sapply(out , function(x) mean(x$data2)) 
# 1 2 
#3.75 6.25 
+2

我想知道'dlply(DF的性能。(userid))',发现它与'split'相比是不好的,即使不涉及'require(plyr)'的运行时间,谢谢你和OP! – Francis

3

偶然发现了这个答案,我其实是想两个组(包含一个用户和数据包含一切,但一个用户数据) 。这篇文章的具体内容不是必需的,但我想我会补充以防有人在Google上搜索同样的问题。

df <- data.frame(
 
    ran_data1=rnorm(125), 
 
    ran_data2=rnorm(125), 
 
    g=rep(factor(LETTERS[1:5]), 25) 
 
) 
 
     
 
test_x = split(df,df$g)[['A']] 
 
test_y = split(df,df$g!='A')[['TRUE']]
这里是什么样子:

head(test_x) 
 
      x   y g 
 
1 1.1362198 1.2969541 A 
 
6 0.5510307 -0.2512449 A 
 
11 0.0321679 0.2358821 A 
 
16 0.4734277 -1.2889081 A 
 
21 -1.2686151 0.2524744 A 
 

 
> head(test_y) 
 
      x   y g 
 
2 -2.23477293 1.1514810 B 
 
3 -0.46958938 -1.7434205 C 
 
4 0.07365603 0.1111419 D 
 
5 -1.08758355 0.4727281 E 
 
7 0.28448637 -1.5124336 B 
 
8 1.24117504 0.4928257 C

相关问题