【问题标题】:New DF column based on the value of another column. Possible new values obtained by checking the name of pre-existing columns with highest value基于另一列的值的新 DF 列。通过检查具有最高值的预先存在的列的名称获得可能的新值
【发布时间】:2019-04-22 12:34:14
【问题描述】:

我有一个带有大量变量(数字和字符,其中也有一些 NA)的数据框(将其称为“df”)。一些列包含特定学校科目的成绩,其他一些列根本不相关。每行代表一个花花公子。

我想创建一个新的(称为“preferedSubject”),其值基于在另一列(“幸福”)中施加的阈值(比如说 0.5);其中,如果此变量的值低于阈值,则该行的“preferedSubject”的值将是一个字符串(比如说...“2Cool4School”),如果更高,该值将成为该行的名称该行中得分最高的学校科目。也就是数值最高的那一列的名称(同时排除了其他一些列,记住有些不是学校科目)

这当然不是我的数据;只是决定将它用作正在发生的事情的基本且(希望是清晰的)示例,出于某种原因,我总能找到一种方法来将其放在学校科目和学生方面。

我相信我的问题的第一部分应该可以使用 ifelse 函数轻松处理;这样我就可以根据“幸福度”是否低于 0.5 为“首选主题”分配一个值。 给我带来麻烦的部分是第二个,我无法找到一种方法来检索得分最高的列(学校科目)的名称,同时首先排除其他一些列(非学校科目)。

假设这是我的数据框:

df <- structure(list(Average = c(7.5, 9, 6, NA), Total = c(22.5, 27, 
18, NA), Happiness = c(0.7, 1, 0.3, 0.5), Math = c(8, 9, 5, 10
), History = c(7, 8, 9, NA), Unrelated1 = structure(c(2L, 3L, 
1L, NA), .Label = c("A. Einstein", "D. DeVito", "M. Curie"), class = "factor"), 
    Chemistry = c(7.5, 10, 4, 7), Unrelated2 = structure(c(2L, 
    1L, 2L, 2L), .Label = c("F", "M"), class = "factor")), class = "data.frame", row.names = c(NA, 
-4L))

### Average Total Happiness Math History  Unrelated1 Chemistry Unrelated2
### 1     7.5  22.5       0.7    8       7   D. DeVito       7.5          M
### 2     9.0  27.0       1.0    9       8    M. Curie      10.0          F
### 3     6.0  18.0       0.3    5       9 A. Einstein       4.0          M
### 4      NA    NA       0.5   10      NA        <NA>       7.0          M

我一直在玩我得到的这段代码,它返回具有最高值的给定向量的位置(学校学科列名称):

apply(df[, c("Math", "History", "Chemistry")], 1, which.max)

在本例中运行它会返回

[1] 1 3 2 1

所以“数学”、“化学”、“历史”和“数学”...确实是数据框中每个人得分最高的学校科目。

但是;由于还有其他专栏,我无法让它以这样一种方式工作,我可以简单地执行以下操作:

apply(df, 1, function(x) {
  x[['preferedSubject']] <- ifelse(x[['Happiness']] < 0.5, "2Cool4School", functionthatshouldreturnwhatIasked(x))
  x
})

所以我希望这样的输出是一个新列,用于检查“幸福”是否高于 0.5。如果是,则其指定值为得分较高的列的名称(不包括Average、Total、Hapiness、Unrelated1和Unrelated2);如果不是,它的指定值就是'2Cool4School'

### Average Total Happiness Math History  Unrelated1 Chemistry Unrelated2 preferedSubject
### 1     7.5  22.5       0.7    8       7   D. DeVito       7.5          M            Math
### 2     9.0  27.0       1.0    9       8    M. Curie      10.0          F       Chemistry
### 3     6.0  18.0       0.3    5       9 A. Einstein       4.0          M      2Cool4School
### 4      NA    NA       0.5   10      NA        <NA>       7.0          M            Math

我是一名生物学家,对 R 很陌生;我想我应该开始用另一种语言编程,但到目前为止我很喜欢它。我已经完成了 2 个教程,如果有人有好的指南/教程/网站推荐,我很乐意接受!

提前致谢!非常感谢任何帮助。

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以使用ifelsemax.col,将NAs 替换为0,然后获取每行中最大值的索引。

    cols <- c("Math", "History", "Chemistry")
    
    df$preferedSubject <- ifelse(df$Happiness >= 0.5, 
             cols[max.col(replace(df[cols], is.na(df[cols]), 0))], "2Cool4School")
    
    df
    #  Average Happiness Math History  Unrelated1 Chemistry Unrelated2 preferedSubject
    #1     7.5       0.7    8       7   D. DeVito       7.5          M            Math
    #2     9.0       1.0    9       8    M. Curie      10.0          F       Chemistry
    #3     6.0       0.3    5       9 A. Einstein       4.0          M    2Cool4School
    #4      NA       0.5   10      NA        <NA>       7.0          M            Math
    

    或者使用applywhich.max的OP方法

    df$preferedSubject <- ifelse(df$Happiness >= 0.5, 
                        cols[apply(df[cols], 1, which.max)], "2Cool4School")
    

    【讨论】:

    • 嘿!非常感谢。刚刚用我的真实数据集试了一下,效果很好(必须想办法将“学校科目”存储到“cols”向量中,因为在我的数据中不止3个哈哈)。不知道 max.col 函数,只是阅读它,会弄清楚它为什么在这里工作,因为文档说它适用于数值矩阵。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2021-07-14
    • 2022-01-05
    • 1970-01-01
    • 2019-07-07
    相关资源
    最近更新 更多