基于另一列的值的新DF列。通过检查具有最高值的预先存在的列的名称获得的可能的新值

时间:2019-04-22 04:20:35

标签: r

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

我想创建一个新的(将其称为“ preferedSubject”),其值基于在另一列(“幸福”)中施加的阈值(假设为0.5);其中,如果此变量的值小于阈值,则该行的“ preferedSubject”的值将是一个字符串(比方说...“ 2Cool4School”),如果更高,则该值将成为该名称该行中得分最高的学校科目。也就是说,具有最高数值的列的名称(虽然不包括其他一些列,但请记住其中一些不是学校科目)

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

我认为,第一部分问题应该使用ifelse函数轻松处理;这样,我可以根据“幸福度”是否小于0.5来为“ preferedSubject”分配一个值。 造成我麻烦的部分是第二个问题,我找不到一种方法来检索得分最高的列(学校科目),而首先排除其他某些列(非学校科目)。

假设这是我的数据框:

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。如果是这样,则它的指定值是得分较高的列的名称(不包括“平均值”,“总计”,“幸福感”,“不相关1”和“不相关2”);如果不是,它的指定值就是'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个教程,如果有人有很好的指南/教程/网站推荐,我很乐意接受!

提前谢谢!非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我们可以使用ifelsemax.col,将NA替换为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

或者将OP的方法与applywhich.max一起使用

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