2015-07-01 43 views
3

我需要为数据框中的每个组选择第2个和第3个条目。我一直在尝试,但得到一个错误。如何为R中的每个组选择第2行和第3行

样本数据:

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'几乎相同的,所以我把它放在这里'''library data.table);或者没有使用'transmute()'和''重新复制第一列,setDT(df)[,':='(restaurant_2 = restaurant [2L],restaurant_3 = restaurant [3L]),by = USER.ID]''' –

+2

nth()':'df%>%group_by(USER.ID)%> transmute(餐厅2 = nth(餐厅,2),restaurant3 = nth(餐厅,3))' –

+1

@people!这是SO。我不拥有这些答案,所以请随时使用编辑按钮:-) – A5C1D2H2I1M1N2O1R2T1

0

如果你在你的数据帧的行名字一个简单的命令,使用模运算符也可能是很长的路要走(在下面选择每个第2行,将2改为n来选择每个第n行):

mydf %>% filter(as.numeric(row.names(.)) %% 2 == 0) 
相关问题