R根据多个列值将数据框子化为多个数据框
Posted
技术标签:
【中文标题】R根据多个列值将数据框子化为多个数据框【英文标题】:R subsetting a data frame into multiple data frames based on multiple column values 【发布时间】:2013-02-28 21:52:02 【问题描述】:我正在尝试对数据框进行子集化,其中我根据多个列值获取多个数据框。这是我的例子
>df
v1 v2 v3 v4 v5
A Z 1 10 12
D Y 10 12 8
E X 2 12 15
A Z 1 10 12
E X 2 14 16
预期的输出是这样的,我根据列 v1
和 v2
将此数据帧拆分为多个数据帧
>df1
v3 v4 v5
1 10 12
1 10 12
>df2
v3 v4 v5
10 12 8
>df3
v3 v4 v5
2 12 15
2 14 16
我编写了一个现在可以运行的代码,但我认为这不是最好的方法。必须有更好的方法来做到这一点。假设tab
是具有初始数据的data.frame。这是我的代码:
v1Factors<-levels(factor(tab$v1))
v2Factors<-levels(factor(tab$v2))
for(i in 1:length(v1Factors))
for(j in 1:length(v2Factors))
subsetTab<-subset(tab, v1==v1Factors[i] & v2==v2Factors[j], select=c("v3", "v4", "v5"))
print(subsetTab)
有人可以提出更好的方法来完成上述操作吗?
【问题讨论】:
您想重复使用这些数据帧,还是只打印按这些列分组的数据? 我想重复使用它们....想在这些数据帧上绘制图表。 【参考方案1】:您正在寻找split
split(df, with(df, interaction(v1,v2)), drop = TRUE)
$E.X
v1 v2 v3 v4 v5
3 E X 2 12 15
5 E X 2 14 16
$D.Y
v1 v2 v3 v4 v5
2 D Y 10 12 8
$A.Z
v1 v2 v3 v4 v5
1 A Z 1 10 12
如 cmets 中所述
以下任何一种都可以使用
library(microbenchmark)
microbenchmark(
split(df, list(df$v1,df$v2), drop = TRUE),
split(df, interaction(df$v1,df$v2), drop = TRUE),
split(df, with(df, interaction(v1,v2)), drop = TRUE))
Unit: microseconds
expr min lq median uq max neval
split(df, list(df$v1, df$v2), drop = TRUE) 1119.845 1129.3750 1145.8815 1182.119 3910.249 100
split(df, interaction(df$v1, df$v2), drop = TRUE) 893.749 900.5720 909.8035 936.414 3617.038 100
split(df, with(df, interaction(v1, v2)), drop = TRUE) 895.150 902.5705 909.8505 927.128 1399.284 100
似乎interaction
稍微快一些(可能是因为f = list(...)
刚刚转换为函数内的交互)
编辑
如果您只想使用子集 data.frames,那么我建议使用 data.table 以方便编码
library(data.table)
dt <- data.table(df)
dt[, plot(v4, v5), by = list(v1, v2)]
【讨论】:
split
可以获取f
的列表,而不必使用interaction
。但不确定哪个更有效。
感谢基准测试。在这种情况下,@Arun 的伎俩(with(df, split(df, f = do.call(paste, df[1:2])))
可能会更快!而且,这不会造成需要删除的不必要关卡。
@mnel 感谢您的及时回复。你的建议似乎确实有效。但并没有完全得到您建议的多种方法的区别。
@mnel 看起来交互创建了所有可能的关卡组合。但是当我运行上述示例时,它并没有创建所有级别。为什么这样??在实际的数据集中,它正在创建....这让我感到莫名其妙。【参考方案2】:
现在还有来自tidyr
的nest()
,相当不错。
library(tidyr)
nestdf <- df %>% nest(v3:v5)
nestdf$data
> nestdf$data
[[1]]
# A tibble: 2 × 3
v3 v4 v5
<int> <int> <int>
1 1 10 12
2 1 10 12
[[2]]
# A tibble: 1 × 3
v3 v4 v5
<int> <int> <int>
1 10 12 8
[[3]]
# A tibble: 2 × 3
v3 v4 v5
<int> <int> <int>
1 2 12 15
2 2 14 16
使用nestdf$data[1]
等访问各个小标题。
【讨论】:
以上是关于R根据多个列值将数据框子化为多个数据框的主要内容,如果未能解决你的问题,请参考以下文章