6

假设我在R中有一个数据框,其中一列中有学生的姓名,另一列中有他们的分数。这些分数从 20 到 100 不等。

> mydata  
id  name   marks gender  
1   a1    56     female  
2   a2    37      male  

我想根据获得分数的标准将学生分组,使每组分数之间的差异应该大于 10。我尝试使用函数表,它给出了每个范围内的学生人数,例如20-30, 30-40,但我希望它选择那些在给定范围内得分的学生,并将他们所有的信息放在一个组中。任何帮助表示赞赏。

4

3 回答 3

9

我不确定“将他们的所有信息放在一个组中”是什么意思,但这是一种获取数据框列表的方法,该列表将您的原始数据框拆分,其中每个元素都是标记内学生的数据框范围 10:

mydata <- data.frame(
  id = 1:100,
  name = paste0("a",1:100),
  marks = sample(20:100,100,TRUE),
  gender = sample(c("female","male"),100,TRUE))

split(mydata,cut(mydata$marks,seq(20,100,by=10)))
于 2012-09-07T09:54:36.587 回答
5

我认为@Sacha 的回答应该足以满足您的需要,即使您有不止一套。

您没有明确说明您希望如何在原始帖子中“分组”数据,并且在您添加第二个数据集的评论中,您没有明确说明您是否打算首先“合并”这些数据(rbind正如评论中所建议的那样就足够了)。

因此,这里有几个选项,每个选项在输出中都有不同级别的详细信息或实用程序。希望其中之一适合您的需求。

首先,这里有一些示例数据。

# Two data.frames (myData1, and myData2)
set.seed(1)
myData1 <- data.frame(id = 1:20, 
                      name = paste("a", 1:20, sep = ""),
                      marks = sample(20:100, 20, replace = TRUE),
                      gender = sample(c("F", "M"), 20, replace = TRUE))
myData2 <- data.frame(id = 1:17,
                      name = paste("b", 1:17, sep = ""),
                      marks = sample(30:100, 17, replace = TRUE),
                      gender = sample(c("F", "M"), 17, replace = TRUE))

其次,“分组”的不同选择。

  • 选项 1:返回(在 a 中listmyData1myData2给定条件匹配的值。对于这个例子,你最终会得到一个包含两个data.frames 的列表。

    lapply(list(myData1 = myData1, myData2 = myData2), 
           function(x) x[x$marks >= 30 & x$marks <= 50, ])
    
  • 选项 2:返回(在 a 中list)每个数据集分成两个,一个用于FALSE(不符合规定的条件),一个用于TRUE(确实符合规定的条件)。换句话说,创建四个组。对于此示例,您最终将得到一个包含两个列表项的嵌套列表,每个列表项都有两个data.frames。

    lapply(list(myData1 = myData1, myData2 = myData2), 
           function(x) split(x, x$marks >= 30 & x$marks <= 50))
    
  • 选项 3:比第一个更灵活。这本质上是将@Sacha 的示例扩展到一个列表。你可以在任何地方设置你的休息时间,在我看来,这是一个非常方便的选择。对于此示例,您最终将得到一个包含两个列表项的嵌套列表,每个列表项都有多个data.frames。

    lapply(list(myData1 = myData1, myData2 = myData2),
           function(x) split(x, cut(x$marks, 
                                    breaks = c(0, 30, 50, 75, 100), 
                                    include.lowest = TRUE)))
    
  • 选项 4:首先组合数据并使用选项 1 中描述的分组方法。对于此示例,您最终将得到一个data.frame仅包含与给定条件匹配的值的单个数据。

    # Combine the data. Assumes all the rownames are the same in both sets
    myDataALL <- rbind(myData1, myData2)
    # Extract just the group of scores you're interested in
    myDataALL[myDataALL$marks >= 30 & myDataALL$marks <= 50, ]
    
  • 选项5:使用组合数据,split将数据分为两组:一组符合规定条件,另一组不符合。对于此示例,您最终将得到一个包含两个data.frames 的列表。

    split(myDataALL, myDataALL$marks >= 30 & myDataALL$marks <= 50)
    

我希望这些选项之一满足您的需求!

于 2012-09-07T12:20:18.833 回答
1

我遇到了同样的问题,在研究了一些关于堆栈溢出的答案后,我想出了以下解决方案:

第 1 步:定义范围 第 2 步:查找范围内的元素 第 3 步:绘图

示例代码如下所示:

   range = NULL
   for(i in seq(0, max(all$downlink), 2000)){
    range <- c(range, i)
   }
   counts <- numeric(length(range)-1);
   for(i in 1:length(counts)) {
   counts[i] <- length(which(all$downlink>=range[i] & all$downlink<range[i+1]));
   }
   countmax = max(counts)
   a = round(countmax/1000)*1000
   barplot(counts, col= rainbow(16), ylim = c(0,a))
于 2015-07-07T14:25:07.367 回答