2010-10-12 7 views
4

У меня есть дата-карта с миллионами строк и трех столбцов с надписью «Ключевые слова», «Впечатления», «Клики». Я хотел бы добавить столбец со значениями в зависимости от оценки этой функции:Добавление столбца на основе других значений

isType <- function(Impressions, Clicks) 
{ 
if (Impressions >= 1 & Clicks >= 1){return("HasClicks")} else if (Impressions >=1 & Clicks == 0){return("NoClicks")} else {return("ZeroImp")} 
} 

пока все хорошо. Затем я пытаюсь создать столбец, но 1) он берет навсегда и 2) он отмечает, что все строки имеют «HasClicks», даже те, где он не должен.

# Creates a dataframe 
Type <- data.frame() 
# Loops until last row and store it in data.frame 
for (i in c(1:dim(Mydf)[1])) {Type <- rbind(Type,isType(Mydf$Impressions[i], Mydf$Clicks[i]))} 
# Add the column to Mydf 
Mydf <- transform(Mydf, Type = Type) 

входных данных:

Ключевые слова, показы, клики
"Привет", 0,0
"Мир", 1,0
"R", 34,23

Требуемый объем производства:

Ключевые слова, впечатления, клики, тип
"Hello", 0,0, "ZeroImp"
"Мир", 1,0, "NoClicks"
"R", 34,23, "HasClicks"

ответ

10

Опираясь на решение Джошуа, я считаю, что очиститель для создания типа в одном кадре (обратите внимание, однако, что это предполагающую Clicks> = 0 ...)

Mydf$Type = ifelse(Mydf$Impressions >= 1, 
    ifelse(Mydf$Clicks >= 1, 'HasClicks', 'NoClicks'), 'ZeroImp') 
+0

Спасибо! Я пришел к такому же выводу, что нужно было использовать ifelse. Я слишком новичок в R, чтобы понять, почему, но спасибо! – datayoda

+0

@ datayoda: 'if()' допускает только одно условие. То есть он допускает или использует только один TRUE или FALSE. В вашем коде вы получили много значений TRUE/FALSE, и только первый из них будет использоваться. В предложении 'if()' вы также не должны использовать '&', поскольку это векторизован и выполняется сравнение для каждого элемента связанных векторов. '&&' предназначен для сравнения одиночных значений. Сравните: 'runif (10)> 0.5 & runif (10)> 0,3' с' runif (10)> 0,5 && runif (10)> 0,3'. Если одна или несколько из первой версии FALSE, вторая ('&&') версия вернет общий FALSE. 'ifelse' является векторизованным' if'. –

3

Во-первых, если/иначе блок в функции возвращает предупреждение:

сообщение Внимание:
В случае (1: 2> 2: 3) TRUE, иначе FALSE:
условие имеет длину> 1 и первый элемент будет использован только

что объясняет, почему это все строки находятся тоже самое.

Во-вторых, вы должны выделить свой файл data.frame и заполнить элементы, а не повторно комбинировать объекты вместе. Я предполагаю, что это заставляет вас долго ждать.

EDIT: Мой общий код. Я бы хотел, чтобы кто-то предоставил более элегантное решение.

Mydf <- data.frame(
    Keywords = sample(c("Hello","World","R"),20,TRUE), 
    Impressions = sample(0:3,20,TRUE), 
    Clicks = sample(0:3,20,TRUE)) 

Mydf$Type <- "ZeroImp" 
Mydf$Type <- ifelse(Mydf$Impressions >= 1 & Mydf$Clicks >= 1, 
    "HasClicks", Mydf$Type) 
Mydf$Type <- ifelse(Mydf$Impressions >= 1 & Mydf$Clicks == 0, 
    "NoClicks", Mydf$Type) 
+0

Не могли бы вы поделиться какой-то код? – datayoda

0

Это тот случай, когда арифметика может быть более чистым и, скорее всего, быстрее, чем вложенные операторы ifelse.

Снова опираясь на решение Иешуа:

Mydf$Type <- factor(with(Mydf, (Impressions>=1)*2 + (Clicks>=1)*1), 
        levels=1:3, labels=c("ZeroImp","NoClicks","HasClicks")) 
Смежные вопросы