R 由两个因素进行分组,所有级别,带有简单代码
我知道这个问题很简单,但如果不创建step对象,就无法找到解决方案,我需要一行代码,或者尽可能简单的代码 假设我有一个名为df的数据帧,其中包含x、y、z列: 在这种情况下,如何访问每个子集 我在一个R 由两个因素进行分组,所有级别,带有简单代码,r,subset,lapply,R,Subset,Lapply,我知道这个问题很简单,但如果不创建step对象,就无法找到解决方案,我需要一行代码,或者尽可能简单的代码 假设我有一个名为df的数据帧,其中包含x、y、z列: 在这种情况下,如何访问每个子集 我在一个lappy中尝试了嵌套的split,但没有成功 很抱歉,这个问题很简单,但无法找到合适的解决方案 任何帮助都将不胜感激。这里有一种方法。使用变量x拆分df。然后,使用变量y再次拆分每个数据帧。通过这种方式,您可以按照您想要的方式对数据进行子集 lapply(split(df, f = df$x),
lappy
中尝试了嵌套的split
,但没有成功
很抱歉,这个问题很简单,但无法找到合适的解决方案
任何帮助都将不胜感激。这里有一种方法。使用变量x拆分df。然后,使用变量y再次拆分每个数据帧。通过这种方式,您可以按照您想要的方式对数据进行子集
lapply(split(df, f = df$x), function(x) split(x, f = x$y)
#$place1
#$place1$type1
# x y z
#5 place1 type1 46
#7 place1 type1 41
#$place1$type2
# x y z
#3 place1 type2 44
#4 place1 type2 59
如果只需要z的值,可以执行以下操作:
[[place1]]
[type1]
[1] 57 73 74 47 52 61
[type2]
[1] 72 76 64 62 73 75
...
[type5]
...
[[place3]]
[type1]
...
[type5]
lapply(split(df, f = df$x), function(x) split(x$z, f = x$y))
#$place1
#$place1$type1
#[1] 46 41 50 59 54 51 66 70
#$place1$type2
#[1] 44 59 60 53 74 46 67 70
#$place1$type3
#[1] 63 70 80 44 73 74 58
#$place1$type4
#[1] 45 67 52 72 45 48 79 65
#$place1$type5
#[1] 75 54
编辑
看到@user295691提供的链接,您还可以执行以下操作
split(df$z, interaction(df$x,df$y))
如果希望每个向量都具有z值,可以执行以下操作:
list2env(split(df$z, interaction(df$x,df$y)), .GlobalEnv)
EDIT2
OP希望使用此数据运行统计数据。一、 因此,我认为留下以下内容是个好主意。如果需要在列表中创建具有不同长度向量的数据帧,可以执行以下操作listvectors2df
允许您使用NA创建数据帧
ana <- split(df$z, interaction(df$x,df$y))
# I used a good answer in this post and wrote the following.
#http://stackoverflow.com/questions/15201305/how-to-convert-a-list-consisting-of-vector-of-different-lengths-to-a-usable-data
listvectors2df <- function(l){
n.obs <- sapply(l, length)
seq.max <- seq_len(max(n.obs))
mydf <- data.frame(sapply(l, "[", i = seq.max), stringsAsFactors = FALSE)
}
bob <- listvectors2df(ana)
ana有两种解决方案。第一个是爵士乐提供的lapply/split。您还可以将这些因素组合成单个因素,例如:
> split(df, paste(df$x, df$y))
$`place1 type1`
x y z
3 place1 type1 57
24 place1 type1 54
$`place1 type2`
x y z
1 place1 type2 67
6 place1 type2 75
7 place1 type2 72
12 place1 type2 57
...
另一种解决方案是使用对多级分组具有内在支持的库,如data.tables
或plyr
/dplyr
。在dplyr
中,操作如下所示(包括摘要,在本例中为第三列的平均值和最大值)
也可以将拆分与交互一起使用:
split(df, interaction(x,y))
$place1.type1
x y z
6 place1 type1 57
25 place1 type1 55
27 place1 type1 55
28 place1 type1 75
29 place1 type1 54
$place2.type1
x y z
36 place2 type1 70
42 place2 type1 69
45 place2 type1 78
57 place2 type1 79
59 place2 type1 46
60 place2 type1 45
63 place2 type1 73
64 place2 type1 79
$place3.type1
x y z
85 place3 type1 54
要访问每个元素,请执行以下操作:
> ll = split(df, interaction(x,y))
>
> ll[[1]]
x y z
6 place1 type1 57
25 place1 type1 55
27 place1 type1 55
28 place1 type1 75
29 place1 type1 54
>
> ll[[2]]
x y z
36 place2 type1 70
42 place2 type1 69
45 place2 type1 78
57 place2 type1 79
59 place2 type1 46
60 place2 type1 45
63 place2 type1 73
64 place2 type1 79
data.table也可用于:
library(data.table)
dtt = data.table(df)
dtt[order(x,y),list(meanz=mean(z), maxz=max(z), sumz=sum(z)),by=list(x,y)]
x y meanz maxz sumz
1: place1 type1 63.11111 80 568
2: place1 type2 68.12500 79 545
3: place1 type3 58.80000 76 294
4: place1 type4 59.83333 79 359
5: place1 type5 59.40000 80 297
6: place2 type1 55.85714 69 391
7: place2 type2 59.71429 71 418
8: place2 type3 61.00000 76 305
9: place2 type4 53.63636 71 590
10: place2 type5 44.66667 46 134
11: place3 type1 62.16667 74 373
12: place3 type2 63.42857 80 444
13: place3 type3 64.00000 77 384
14: place3 type4 61.28571 80 429
15: place3 type5 51.00000 60 408
也发现,它提供了一些其他的建议,这也给这个解决方案留下了深刻的印象。这对我很有帮助。谢谢。非常感谢你的回答。这正是我想要的。而且,我想访问z列,并将其作为每个列表元素中的向量,而不是df中的所有列。这可能吗?@JoseRamon非常感谢您的评论。我想知道lappy(split(df,f=df$x),function(x)split(x$z,f=x$y))
是否实现了您提到的功能。如果您想要每个向量,可以执行类似于list2env(拆分(df$z,交互(df$x,df$y)),.GlobalEnv的操作。。然后,键入ls()
。您将看到所有向量。如果这是您想要的,请告诉我。我刚刚测试了list2env
解决方案。不知道可以为每个列表元素创建一个向量。这对我来说真的很有用,不仅对于这个问题,而且对于我遇到的许多其他问题。现在我们已经进入这一步,让我问你另一个问题:我可以在所有可能的对之间运行一个wilcox.test
(当然不是成对的)吗?例如:place1.type1与place1.type2…place5.type4与place5.type5。Thanks@JoseRamon让我想想我能尝试什么。我明天给你回电。@JoseRamon我想我不能在这里写所有的东西。但是,首先要创建一个数据帧。检查。您可以学习如何装箱df。我使用dplyr
运行了wilcox.test。不能运行所有对。但是您可以使用一列对其余列运行测试。如果mydf是您的df,您可以这样做:mydf%>%summary_each(funs(wilcox.test(place1.type1,)$p.value),vars=place2.type1:place3.type5)。由于关系,您有警告。希望这对您有所帮助。从packagedata.table
和split的interaction
参数得到的解决方案非常有趣。谢谢
> ll = split(df, interaction(x,y))
>
> ll[[1]]
x y z
6 place1 type1 57
25 place1 type1 55
27 place1 type1 55
28 place1 type1 75
29 place1 type1 54
>
> ll[[2]]
x y z
36 place2 type1 70
42 place2 type1 69
45 place2 type1 78
57 place2 type1 79
59 place2 type1 46
60 place2 type1 45
63 place2 type1 73
64 place2 type1 79
library(data.table)
dtt = data.table(df)
dtt[order(x,y),list(meanz=mean(z), maxz=max(z), sumz=sum(z)),by=list(x,y)]
x y meanz maxz sumz
1: place1 type1 63.11111 80 568
2: place1 type2 68.12500 79 545
3: place1 type3 58.80000 76 294
4: place1 type4 59.83333 79 359
5: place1 type5 59.40000 80 297
6: place2 type1 55.85714 69 391
7: place2 type2 59.71429 71 418
8: place2 type3 61.00000 76 305
9: place2 type4 53.63636 71 590
10: place2 type5 44.66667 46 134
11: place3 type1 62.16667 74 373
12: place3 type2 63.42857 80 444
13: place3 type3 64.00000 77 384
14: place3 type4 61.28571 80 429
15: place3 type5 51.00000 60 408