2015-07-01 1 views
3

Мне нужно выбрать 2-ю и 3-ю позицию для каждой группы в кадре данных. Я пытался получить ошибку.Как выбрать вторую и третью строку для каждой группы в R

Образец данных:

USER.ID restaurant 
3   aaaa 
3   ababa 
3   asddw 
4   bbbb 
4   wedwe 
2   ewedw 
1   qwqw 
1   dwqd 
1   dqed 
1   ewewq 

Желаемый результат:

USER.ID 2nd_restaurant 3rd_restaurant 
3   ababa    asddw 
3   ababa    asddw 
3   ababa    asddw 
4   wedwe    NA 
4   wedwe    NA 
2   NA    NA 
1   dwqd    dqed 
1   dwqd    dqed 
1   dwqd    dqed 
1   dwqd    dqed 

Я попытался с помощью dplyr, но я предполагаю, что из-за огромного объема данных, это занимает много времени, чтобы вычислить. Есть ли способ вычислить его более эффективно?

Мой код:

data1 <- data %>% 
arrange(USER.ID) %>% 
group_by(USER.ID) %>% 
mutate(second_restaurant = data[2,11]) %>% 
mutate(third_restaurant = data[3,11]) 

11 это номер столбца ресторана в исходном наборе данных.

ответ

5

Скопируйте столбец ресторан первым, а затем использовать mutate извлечь соответствующие значения:

mydf %>% 
    mutate(restaurant2 = restaurant) %>% 
    group_by(USER.ID) %>% 
    mutate(restaurant = restaurant[2], restaurant2 = restaurant2[3]) 
# Source: local data frame [10 x 3] 
# Groups: USER.ID 
# 
# USER.ID restaurant restaurant2 
# 1  3  ababa  asddw 
# 2  3  ababa  asddw 
# 3  3  ababa  asddw 
# 4  4  wedwe   NA 
# 5  4  wedwe   NA 
# 6  2   NA   NA 
# 7  1  dwqd  dqed 
# 8  1  dwqd  dqed 
# 9  1  dwqd  dqed 
# 10  1  dwqd  dqed 

Или, еще лучше (любезность @ StevenBeaupré):

mydf %>% 
    group_by(USER.ID) %>% 
    transmute(restaurant2 = nth(restaurant, 2), 
      restaurant3 = nth(restaurant, 3)) 

Или, если вы предпочитаете «data.table», перефразируя @DavidArenburg, вы можете попробовать:

library(data.table) 
as.data.table(mydf)[, `:=`(restaurant_2 = restaurant[2L], 
          restaurant_3 = restaurant[3L]), by = USER.ID][] 

Или, вы можете даже использовать базовый R:

mydf[c("restaurant_2", "restaurant_3")] <- with(mydf, lapply(c(2, 3), function(x) { 
    ave(restaurant, USER.ID, FUN = function(y) y[x]) 
})) 
+3

Я собирался отправить почти то же самое с 'data.table', так что я положу его здесь' '' библиотека (Таблица данных) ; setDT (df) [, ': =' (restaurant_2 = ресторан [2L], restaurant_3 = ресторан [3L]), by = USER.ID] '' ' –

+2

Или не переписывая первый столбец с помощью' transformute() 'и' nth() ':' df%>% group_by (USER.ID)%>% transformute (restaurant2 = nth (ресторан, 2), restaurant3 = nth (ресторан, 3)) ' –

+1

@people! Это так. Я не владею этими ответами, поэтому не стесняйтесь использовать кнопку редактирования :-) – A5C1D2H2I1M1N2O1R2T1

0

Если у вас есть простой порядок в названиях строк вашего кадра данных, с помощью оператора по модулю может быть также путь (Ниже Выделяет каждый 2-й ряд, изменение 2 п для выбора каждого п-ю строку):

mydf %>% filter(as.numeric(row.names(.)) %% 2 == 0) 
Смежные вопросы