Новый столбец DF на основе значения другого столбца.Возможные новые значения, полученные путем проверки имени ранее существующих столбцов с наибольшим значением - PullRequest
1 голос
/ 22 апреля 2019

У меня есть фрейм данных (назовем его 'df') с приличным количеством переменных (числовые и символьные, там тоже есть некоторые NA).Некоторые из столбцов содержат оценку определенного школьного предмета, некоторые другие столбцы вообще не связаны.В каждой строке представлен чувак.

Я хочу создать новый (назовем его «PreredSubject») со значениями, основанными на пороге (скажем, 0,5), наложенном в другом столбце («Счастье»);где, если значение этой переменной ниже, чем пороговое значение, значением 'PreredSubject' для этой строки будет строка (скажем ... '2Cool4School'), и, если оно выше, значение станет именемшкольный предмет с самым высоким баллом из этого ряда.То есть имя столбца с наибольшим числовым значением (исключая некоторые другие столбцы, помните, что некоторые из них не являются школьными предметами)

Это, конечно, не мои данные;Я просто решил использовать это как основной и (надеюсь, понятный) пример того, что происходит, по какой-то причине я всегда нахожу способ выразить это с точки зрения школьных предметов и учащихся.

Первая часть моей проблемыдолжно быть легко обработано с помощью функции ifelse, которую я считаю;таким образом, я могу присвоить значение для «PreredSubject» в зависимости от того, является ли «Happyness» ниже 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 или нет.Если это так, его назначаемое значение - это имя столбца с более высоким баллом (исключая Среднее, Общее, Счастье, Несвязанный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 голосов
/ 22 апреля 2019

Мы могли бы использовать ifelse и max.col, заменив NA s на 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 с apply и which.max

df$preferedSubject <- ifelse(df$Happiness >= 0.5, 
                    cols[apply(df[cols], 1, which.max)], "2Cool4School")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...