2014-09-07 2 views
0

Сначала я очень новичок в R, и я знаю, что я могу сделать очевидную ошибку, я искал ответ, но возможно, я искал неправильную вещь.dplyr - имена уровней фактора, которые не принимаются должным образом в мутате при использовании rowwise()

Я пытаюсь применить функцию для добавления нового столбца в dataframe на основе содержимого этой строки. Но мне кажется, что значения в строке не обрабатываются должным образом в функции mutate при использовании rowwise. Я попытался создать игрушечный пример, чтобы продемонстрировать свою проблему.

library(dplyr)  
x<-c("A,"B") 
y<-c(1,2) 
df<-data.frame(x,y) 

Тогда у меня есть функция, чтобы создать новый столбец с именем z, который добавляет 1 к y если значение x является "A" и добавляет 2 к y если значение x является "B". Заметьте, что я добавил print(x), чтобы показать, что происходит.

calculatez <- function(x,y){ 
    print(x) 
    if(x == "A"){ 
    return (y+1) 
    } 
    else{ 
    return(y+2) 
    } 
} 

Затем я пытаюсь использовать mutate:

df %>% 
    rowwise() %>% 
    mutate(z = calculatez(x,y)) 

и я получаю следующее, 2 был добавлен в обоих рядах, а не 1 к первой строке и "A" и "B" были приняты в функцию 1 и 2.

[1] 1 
[1] 2 
Source: local data frame [2 x 3] 
Groups: 

    x y z 
1 A 1 3 
2 B 2 4 

Если удалить функцию rowwise()"A" и "B" по всей видимости, передается правильно, но явно не получите нужного результата.

df %>% 
    mutate(z = calculatez(x,y)) 

[1] A B 
Levels: A B 
    x y z 
1 A 1 2 
2 B 2 3 
Warning message: 
In if (x == "A") { : 
    the condition has length > 1 and only the first element will be used 

я могу заставить его работать, если я попытаюсь сделать это без написания собственной функции, а затем я не получаю сообщение об ошибке о длине состояния. Поэтому я не думаю, что правильно понимаю, что делает rowwise().

df %>% 
    mutate(z = ifelse(x=="A",y+1,y+2)) 

    x y z 
1 A 1 2 
2 B 2 4 

Но я хочу, чтобы иметь возможность использовать свою собственную функцию, потому что в моем реальном приложении условие является более сложным, и будет трудно читать с большим количеством вложенных ifelse функций в функции mutate.

Я могу обойти проблему, изменив мое состояние на if(x==1), но это затруднит понимание моего кода.

Я не хочу тратить ваше время, так что извините, если мне не хватает чего-то очевидного. Какие-нибудь советы о том, где я ошибаюсь?

ответ

1

Вы можете использовать rowwise с do

df %>% 
rowwise() %>% 
do(data.frame(., z= calculatez(.$x, .$y))) 

дает выходной сигнал

 x y z 
    #1 A 1 2 
    #2 B 2 4 

Или вы могли бы сделать:

df %>% 
    group_by(N=row_number()) %>% 
    mutate(z=calculatez(x,y))%>% 
    ungroup() %>% 
    select(-N) 

Использование другого набора данных:

df <- structure(list(x = structure(c(1L, 1L, 2L, 2L, 2L), .Label = c("A", 
"B"), class = "factor"), y = c(1, 2, 1, 2, 1)), .Names = c("x", 
"y"), row.names = c(NA, -5L), class = "data.frame") 

Запуск выше код дает:

# x y z 
#1 A 1 2 
#2 A 2 3 
#3 B 1 3 
#4 B 2 4 
#5 B 1 3 

Если вы используете data.table

library(data.table) 
setDT(df)[, z := calculatez(x,y), by=seq_len(nrow(df))] 
df 
# x y z 
# 1: A 1 2 
# 2: A 2 3 
# 3: B 1 3 
# 4: B 2 4 
# 5: B 1 3 
+0

Спасибо, это здорово. Теперь я понимаю, как получить то, что я хочу. Я раньше не встречал «делаю», поэтому я буду читать. Но я думаю, я думал, что 'rollise' сделал эквивалент' group_by (N = row_number()) '. Для моего общего понимания любые идеи, почему моя первая попытка не сработала? – tecb1234

+0

@ techb1234 Согласно странице справки? Rowwise() ''rowwise' используется для результатов 'do' при создании list-variables.' По какой-то причине, когда вы комбинируете 'mutate' с row_wise(), только Цикл 'else' из' calculatez' выполнен. – akrun

+0

Да, потому что по какой-то причине значение 'x' передается как' 1' или '2' не' 'A" или '" B "', поэтому my 'if (x ==" A ") 'условие всегда неверно. Но спасибо, что указали мне на страницу справки, похоже, что 'rowwise' предназначен только для работы с' do'. Хорошо знать. – tecb1234

Смежные вопросы