将数据分组到R中的范围

时间:2012-09-07 09:28:49

标签: r grouping

假设我在 R 中有一个数据框,其中一列中的学生名称和另一列中的标记。这些标记从20到100不等。

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

我想根据获得的标记的标准将学生分成小组,这样每组中的标记之间的差异应该大于10.我试着使用功能表,它给出了每个学生的数量。范围从20-30到30-40,但我希望它选择那些在给定范围内有标记并将所有信息放在一起的学生。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分: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)))

答案 1 :(得分:5)

我认为@Sacha的answer应该足以满足你的需要,即使你有多套。

您尚未明确说明如何对原始帖子中的数据进行“分组”,而在您添加第二个数据集的评论中,您尚未明确说明您是否计划“合并”首先这些(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 :返回(listmyData1myData2中与给定条件匹配的值。 对于此示例,您最终会得到两个data.frame的列表。

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

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

    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.frame的列表。

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

我希望其中一个选项满足您的需求!

答案 2 :(得分: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))