有没有办法在r中拆分一个数据帧,然后将其索引到新的数据帧中?

时间:2019-11-21 19:49:09

标签: r dataframe split

我有一个看起来像这样的数据框:

Grade   Class_Dept   Class_Name   Class_Work
9       English      English 1    30
10      History      Modern World 50
11      Science      AP Chem      85
12      Math         Calc BC      45

它的作用远不止于此,但这是普遍的想法。我想通过Class_Name将其拆分为多个较小的数据帧。我尝试使用plyr,但无法弄清楚。我还尝试了split()函数,该函数有效,但不允许我在for循环中索​​引到每个子数据帧。我还有其他方法可以做到吗?任何帮助将不胜感激。

此外,如果我可以索引到每个子数据帧,split()函数将起作用。 如果那没有道理,我想做的就是获取每个Class_Name的Class_Work的均值和标准偏差,并进行比较。我可以使用split()返回的列表手动进行此操作,但是这会花费很长时间,因为我的数据框有大约120个不同的类。如果有一种自动化的方法,那就太好了。

4 个答案:

答案 0 :(得分:3)

您可以使用dplyr::group_split()

library(dplyr)
iris %>%
    group_by(Species) %>%
    group_split()

答案 1 :(得分:0)

如果您尝试拆分和循环,请尝试拆分并lapply / vapply:

vapply(split(mtcars, mtcars$cyl), function(df) mean(df$mpg), double(1))

答案 2 :(得分:0)

似乎真正的目标是从“ Class_Name”分组的总数据集中收集摘要数据,并且确实没有必要将其拆分为不同的数据框。对于base R和dplyr软件包,有几个很好的选择可以执行此摘要。

下面是使用split/sapplytapplygroup_by/summarize技术的示例。

df<-read.table(header=TRUE, text='Grade   Class_Dept   Class_Name   Class_Work
9       English      "English 1"    30
10      History      "Modern World" 50
11      Science      "AP Chem"      85
12      Math         "Calc BC"      45')

#Base R solution
#split into a list of dataframes by Class_name
dflist<-split(df, df$Class_Name)
#perform math operation on each dataframe
workmean<-sapply(dflist, function(x){ mean(x$Class_Work)})
workstdev<-sapply(dflist, function(x){ sd(x$Class_Work)})

workmean
#   AP Chem      Calc BC    English 1 Modern World 
#        85           45           30           50 

#tapply option:
tapply(df$Class_Work, df$Class_Name, mean)
#     AP Chem      Calc BC    English 1 Modern World 
#          85           45           30           50 

#dplyr solution
library(dplyr)
df %>% group_by(Class_Name) %>% summarize(mean=mean(Class_Work), stdev=sd(Class_Work))
# # A tibble: 4 x 3
#   Class_Name    mean stdev
#   <fct>        <dbl> <dbl>
# 1 AP Chem         85   NaN
# 2 Calc BC         45   NaN
# 3 English 1       30   NaN
# 4 Modern World    50   NaN

答案 3 :(得分:0)

您可以data.table包装吗:

> dt <- iris
> setDT(dt)[,.(mean=mean(Petal.Width),std_dv=sd(Sepal.Length)),by=.(Species)]

     Species  mean    std_dv
1:     setosa 0.246 0.3524897
2: versicolor 1.326 0.5161711
3:  virginica 2.026 0.6358796