Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在R中对数据帧进行分组_R_Large Data - Fatal编程技术网

如何在R中对数据帧进行分组

如何在R中对数据帧进行分组,r,large-data,R,Large Data,我有这样一个大数据框: df: 我想很快地把它分成几个小组: df_1: df_2: 我知道有一种方法是这样的: df_1 <- df[df == 1] df_2 <- df[df == 2] 但它并不快。 我该怎么办 感谢提供dplyr和tidyr选项: 欢迎来到SO 我建议看一下dplyr和data.table包,它们专注于快速和内存高效的实现。特别是我要建议的惊人的答案,这将有助于更好地理解这两个包的功能 随着组和重复子集数量的增加,data.table确实会优于dplyr,

我有这样一个大数据框:

df:

我想很快地把它分成几个小组:

df_1:

df_2:

我知道有一种方法是这样的:

df_1 <- df[df == 1]
df_2 <- df[df == 2]
但它并不快。 我该怎么办

感谢提供dplyr和tidyr选项:

欢迎来到SO

我建议看一下dplyr和data.table包,它们专注于快速和内存高效的实现。特别是我要建议的惊人的答案,这将有助于更好地理解这两个包的功能

随着组和重复子集数量的增加,data.table确实会优于dplyr,因为它使用索引和键控子集,但对于大多数情况,它归结为一种偏好。专注于子集,我将提供一个可复制的示例和一些速度比较

可复制示例 dplyr方法 另一种选择是dplyr包。dplyr是语法糖,提供了管道选项,与其他一些包(例如包)没有什么不同,但本文中显示的不同基准表明,该包可以用于提高各个方面的性能。然而,我不是这个软件包的专家,因为我倾向于使用data.table软件包。该软件包提供%>%管道功能和一些实用功能,如可用于子集数据的过滤器

library(dplyr)
df %>% filter(group == "C")
# subsetting two columns
df %>% filter(group == "C", random_binaries == TRUE) #Equivalent to group == "C" & random_binaries == TRUE
数据表方法: 最后一个流行的软件包是软件包。这个包是为性能和内存效率而设计的,就像dplyr一样。语法设计类似于SQL语句,select、from、where、group by,但开始使用语法可能会有点混乱。该包提供了一个新的data.table类,以供使用,而不是data.frame类,后者的子集设置速度非常慢

但是,几乎可以完全忽略包的语法,因为data.table在大多数情况下使用data.frame语法,并且在任何情况下都可以用作data.frame

library(data.table)
#Convert the data.frame to data.table
setDT(df) 
data.table有两种标准方法:使用索引和使用键。如果使用与data.frame方法类似的方法,则使用索引:

语法可能会让人困惑,但你可以看看它们的有用之处,或者今天的8968,它们为大多数问题提供了答案

性能比较 我已经检查了下面显示的子集方法的性能。可视化显示了使用所示方法为group==C和group==H&random_二进制文件==TRUE的子集显示的各种方法。x轴以毫秒为单位指示运行时间,y轴显示方法。 斑点的宽度表示范围,而斑点的大小表示范围内的时间密度

从可视化中可以看出,对于一个包含2列的数据集,在1列和2列上都进行子集设置,使用键的data.table方法标记为data.table_u键的速度要快得多,而使用索引的速度略优于其他方法。使用子集的速度比标准方法慢,令人惊讶的是,在本例中,dplyr比base-R慢,但这可能是因为我对该软件包缺乏经验

这里有一种使用BaseR中的Lappy的方法,它可以为您提供所需数据帧的列表-

df <- data.frame(col_1 = 1, col_2 = 2, col_3 = 1)

lapply(unique(unlist(df)), function(x) {
  df[, df == x, drop = F]
})

# output

[[1]]
  col_1 col_3
1     1     1

[[2]]
  col_2
1     2

您的数据中只有一行吗?如果没有,你能再增加几行,并在此基础上显示预期的输出吗?我只有一行@RonakShahI认为t应该类似于df%>%gatherkey,val%>%group_splitval至少在我的机器上仍然没有达到OP的预期输出。@agila修复了我认为的itor。似乎OP更感兴趣的是按val分组,而不是按键分组,第二眼看到的是你们在那个里写的东西,我错过了。更正了,谢谢。
 df %>% 
  tidyr::gather(key,val) %>% 
  group_split(val)   #attributed to @agila for pointing out the unnenecessary call to group_by that I missed initially
[[1]]
# A tibble: 2 x 2
  key     val
  <chr> <int>
1 col_1     1
2 col_3     1

[[2]]
# A tibble: 1 x 2
  key     val
  <chr> <int>
1 col_2     2

attr(,"ptype")
set.seed(1)
df <- data.frame(group = sample(LETTERS, 1e7, TRUE), 
                 random_numbers = rnorm(1e7), 
                 random_binaries = rbinom(1e7, 1, 0.3))
# size = 152.6 MiB
format(object.size(df), units = "MiB")
df[df$group == "C",]
#Equivalent
df[which(df$group == "C"),]
#Equivalent
subset(df, group == "C")
library(dplyr)
df %>% filter(group == "C")
# subsetting two columns
df %>% filter(group == "C", random_binaries == TRUE) #Equivalent to group == "C" & random_binaries == TRUE
library(data.table)
#Convert the data.frame to data.table
setDT(df) 
df1 <- df[random_binaries == TRUE]
df2 <- df[group == "C"]
#Set the key using either setkey, or setkeyv (multiple columns)
setkeyv(df, c("group", "random_binaries"))
#Subset on group
df[.("C")]
#subset on random_binaries
df[CJ(group, TRUE, unique = TRUE)]
df[.(unique(group), TRUE)]
# Subset on multiple conditions
df[.(c("C", "H"), c(TRUE, TRUE))]
df <- data.frame(col_1 = 1, col_2 = 2, col_3 = 1)

lapply(unique(unlist(df)), function(x) {
  df[, df == x, drop = F]
})

# output

[[1]]
  col_1 col_3
1     1     1

[[2]]
  col_2
1     2