2010-11-14 2 views
1

Хорошо, название может быть не самым наглядным. Это проще объяснить на примере.R: Выбрать ячейки в data.frame на основе другого атрибута в том же экземпляре

У меня есть data.frame вроде этого:

A B 1 2 
L M 3 0 
P Q 5 6 

Я хочу, чтобы вывести массив из ячейки в колонке 1, если col3> COL4, или клетка в col2, если col3 < = COL4. Выходной вектор из этого data.frame будет B, L, Q.

Я знаю, что я до сих пор не объяснили мою проблему очень хорошо, так вот что это будет выглядеть в императивном языке:

vector = [] 
for each rows as row 
    if row[3] > row[4] 
    vector.add(row[1]) 
    else 
    vector.add(row[2]) 
return vector 

Я прошу прощения, если этот вопрос уже был дан ответ, но, к сожалению, Google не очень помогает, когда дело доходит до вопросов R.

Спасибо, Andreas

ответ

3

Это должно работать (при условии, df ваша кадр данных)

apply(df, 1, function(x){ifelse(x[3] > x[4], x[1], x[2])}) 
+3

'ifelse' является векторизация так' IfElse (Д.Ф. [[3]]> df [[4]], df [[1]], df [[2]]) '. – Marek

+0

Отлично, спасибо! –

4

Вашего тест не является достаточно сложным, чтобы раскрыть некоторые из убежищ крокодилов в R, относящихся к объектам class == factor, параметры по умолчанию для data.frame() и использование таких функций, как apply и ifelse. Я мог извиниться за длину ответа, но это действительно просто небольшое подмножество того, что вы можете прочитать в The R Inferno. Допустим, вы создаете data.frame, DFRM:

dfrm <-data.frame(textConnection("A B 2 12 
L M 3 0 
P Q 5 6", header=FALSE) 

ВНИМАНИЕ: Я изменил ваш первый случай немного. Теперь запустите первое предлагаемое решение: вы получите

apply(dfrm, 1, function(x){ifelse(x[3] > x[4], x[1], x[2])}) 
[1] "A" "L" "P" 

Ясно, что 2 не больше 12, так что случилось? Функция apply работает над матрицами и преобразует data.frame в матрицу перед выполнением функции и проверяет «2»> «12», которая является TRUE. Таким образом, крокодил №1 является поведением по умолчанию apply().

ошибки или предупреждения, также являются результатом того, что может показаться на первый и второй взгляд совершенно разумный код R:

vector <- dfrm$V2; 
vector[V3 > V4] <- V1[V3 > V4] 

(Это не было сообщение особенно информативны ошибка, мне в любом случае, ... что-то о NA ... и это было связано с тем, что я пытался присвоить значение объекту фактора, для которого не было существующего уровня.) Это второй крокодил: класс по умолчанию для значений символов для функции data.frame это «фактор», а не «символ».

Третий крокодил поведение IfElse:

with(dfrm, ifelse(V3 > V4, V1, V2)) 
[1] 1 2 3 

ВТФ? Функция ifelse автоматически преобразует коэффициенты в V1 и V2 в их внутренние числовые представления, и это происходит потому, что функция принудительно возвращает возвращаемые значения по типу условных аргументов. Не так, как я бы разработал такую ​​функцию, но эти вещи были разработаны несколько десятилетий назад, поэтому их изменение почти невозможно.Так пару "вправо", или по крайней мере безопаснее, способы сделать работу, которую вы просили: method1:

with(dfrm, ifelse(V3 > V4, as.character(V1), as.character(V2))) 
[1] "B" "L" "Q" 

Method2:

vector <- as.character(dfrm$V2) 
vector[which(dfrm$V3 > dfrm$V4)] <- as.character(dfrm$V1[which(dfrm$V3 > dfrm$V4)]) 
vector 
[1] "B" "L" "Q" 
Смежные вопросы