【问题标题】:Find Closest Matching Value in Data frame and Return Index在数据框中查找最接近的匹配值并返回索引
【发布时间】:2019-12-14 09:17:51
【问题描述】:

我有两个数据框。第一个是一组变量,其中最后一列是每列中值的总和。第二个数据框是一个索引,其中第一列是 rowSum 值可能落入的一组可能值。

我想要做的是将第一个数据帧中的 rowSum 值与第二个数据帧中最接近的值匹配,并返回与第二个数据帧中的值一起出现的值,有点像分配一个基于测试分数的字母等级。

a <- c(1.2, 2.3, 3.4)
b <- c(2.3, 3.4, 4.5)
c <- c(3.4, 4.5, 5.6)
score <- c(6.9, 10.2, 13.5)

Scores <- data.frame(cbind(a,b,c,score))

score <- c(15, 14, 13
       ,12, 11, 10
       ,9, 8, 7
       ,6, 5, 4
       ,3, 2, 1)

grade <-  c('A','A','A'
        ,'B','B','B'
        ,'C','C','C'
        ,'D','D','D'
        ,'F', 'F', 'F')

Grades <- data.frame(cbind(score,grade))


Scores$Grade <-
  Grades$grade[match(Scores$score, Grades$score)]

预期:

a    b    c    score    Grade
1.2  2.3  3.4  6.9      C
2.3  3.4  4.5  10.2     B
3.4  4.5  5.6  13.5     A

实际:

a    b    c    score    Grade
1.2  2.3  3.4  6.9      NA
2.3  3.4  4.5  10.2     NA
3.4  4.5  5.6  13.5     NA

我认为这是因为 match() 无法舍入小数,因此无法匹配精确值。是否有不同的函数或方法可以将值匹配到最接近的匹配整数并返回相应的等级?

【问题讨论】:

  • 试试findInterval。请不要使用data.frame(cbind,因为它会弄乱数据结构,而应该使用data.frame(
  • 试试rev(Grades$grade)[findInterval(Scores$score, rev(Grades$score))]

标签: r match


【解决方案1】:

这可以通过findInterval 完成,但要确保数据集创建正确,cbind 返回一个matrix,而matrix 只能有一个类。使用data.frame 包装将同一类传播到factorcharacter,具体取决于stringsAsFactors = TRUE/FALSE(如果至少有一个character 元素)。

按“分数”列对“成绩”数据集进行排序,并应用findInterval 以获取最接近的匹配值的索引,并将其用于提取“成绩”

Scores <- data.frame(a,b,c,score)
Grades <- data.frame(score,grade)
Grades1 <- Grades[order(Grades$score),]
Scores$Grade <- Grades1$grade[findInterval(Scores$score, Grades1$score) +1]

或者另一种选择是滚动连接

library(data.table)
setDT(Scores)[Grades, Grade := grade, on = .(score), roll = Inf]
Scores
#     a   b   c score Grade
#1: 1.2 2.3 3.4   6.9     C
#2: 2.3 3.4 4.5  10.2     B
#3: 3.4 4.5 5.6  13.5     A

【讨论】:

    猜你喜欢
    • 2012-02-13
    • 2012-02-13
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2018-09-29
    • 2020-02-23
    相关资源
    最近更新 更多