在R中,如何通过多列中的因子对数据帧进行拆分/子集?

时间:2015-03-25 05:13:33

标签: r

我的数据如下:

ID   Test Type       Subject  Marks
1    Unit test 1     English   85
2    Unit test 1     English   75
3    Unit test 1     English   78
1    Unit test 2     English   85
2    Unit test 2     English   75
3    Unit test 2     English   78
1    Unit test 1     Maths     78
2    Unit test 1     Maths     79
3    Unit test 1     Maths     98
1    Unit test 2     Maths     95
2    Unit test 2     Maths     98
3    Unit test 2     Maths     88

我想通过"测试类型"分割数据。和"主题"。我应该使用什么功能? 我想要的结果是:

data frame 1:
    ID   Test Type       Subject  Marks
    1    Unit test 1     English   85
    2    Unit test 1     English   75
    3    Unit test 1     English   78

data frame 2:
    ID   Test Type       Subject  Marks
    1    Unit test 2     English   85
    2    Unit test 2     English   75
    3    Unit test 2     English   78

data frame 3 :
    ID   Test Type       Subject  Marks
    1    Unit test 1     Maths     78
    2    Unit test 1     Maths     79
    3    Unit test 1     Maths     98

data frame 4:
    ID   Test Type       Subject  Marks
    1    Unit test 2     Maths     95
    2    Unit test 2     Maths     98
    3    Unit test 2     Maths     88

3 个答案:

答案 0 :(得分:3)

您可以使用split()(感谢DrDom的改进)。

split(df, list(df$Test.Type, df$Subject))
# $`Unit test 1.English`
#   ID   Test.Type Subject Marks
# 1  1 Unit test 1 English    85
# 2  2 Unit test 1 English    75
# 3  3 Unit test 1 English    78
# 
# $`Unit test 2.English`
#   ID   Test.Type Subject Marks
# 4  1 Unit test 2 English    85
# 5  2 Unit test 2 English    75
# 6  3 Unit test 2 English    78
# 
# $`Unit test 1.Maths`
#   ID   Test.Type Subject Marks
# 7  1 Unit test 1   Maths    78
# 8  2 Unit test 1   Maths    79
# 9  3 Unit test 1   Maths    98
# 
# $`Unit test 2.Maths`
#    ID   Test.Type Subject Marks
# 10  1 Unit test 2   Maths    95
# 11  2 Unit test 2   Maths    98
# 12  3 Unit test 2   Maths    88

其中df是原始数据。

df <- structure(list(ID = c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
2L, 3L), Test.Type = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 1L, 
1L, 1L, 2L, 2L, 2L), .Label = c("Unit test 1", "Unit test 2"), class = "factor"),
    Subject = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
    2L, 2L, 2L), .Label = c("English", "Maths"), class = "factor"), 
    Marks = c(85L, 75L, 78L, 85L, 75L, 78L, 78L, 79L, 98L, 95L, 
    98L, 88L)), .Names = c("ID", "Test.Type", "Subject", "Marks"
), class = "data.frame", row.names = c(NA, -12L))

答案 1 :(得分:1)

另一个简单的解决方案是使用by

list.df <- by(df, INDICES =  list(df$Test.Type, df$Subject), FUN = data.frame)

<强>结果

> list.df
: Unit test 1
: English
  ID   Test.Type Subject Marks
1  1 Unit test 1 English    85
2  2 Unit test 1 English    75
3  3 Unit test 1 English    78
-------------------------------------------------------------------------------------------------- 
: Unit test 2
: English
  ID   Test.Type Subject Marks
4  1 Unit test 2 English    85
5  2 Unit test 2 English    75
6  3 Unit test 2 English    78
-------------------------------------------------------------------------------------------------- 
: Unit test 1
: Maths
  ID   Test.Type Subject Marks
7  1 Unit test 1   Maths    78
8  2 Unit test 1   Maths    79
9  3 Unit test 1   Maths    98
-------------------------------------------------------------------------------------------------- 
: Unit test 2
: Maths
   ID   Test.Type Subject Marks
10  1 Unit test 2   Maths    95
11  2 Unit test 2   Maths    98
12  3 Unit test 2   Maths    88

然后,您可以使用list.df[[1]]list.df[[4]]来访问每个单独的数据框。

(感谢Richard Scriven在答案中dput提供数据。)

答案 2 :(得分:0)

以下是计算每个测试类型/主题组合的平均标记的代码:

# df($testtype, $subject)

> ddply(df, .(testtype, subject), summarize, avgmark = round(mean(marks), 0))

<强>结果:

     testtype subject avgmark
1 Unit Test 1 English      79
2 Unit Test 1   Maths      85
3 Unit Test 2 English      79
4 Unit Test 2   Maths      94

ddply函数将为每个组计算avgmark并返回数据帧结果。您可以将avgmark替换为您想要的任何聚合函数。您还可以在avgmark之后添加更多聚合函数。有关更多信息,请查看此文章。