簡體   English   中英

在dplyr包中使用group_by和mutate通過id變量創建新的factor因子

[英]Using group_by and mutate in dplyr package to create new factor variable by id variable

我有一個長格式的分層數據框,其中每一行代表關系,其中許多可以屬於一個人。 以下是小示例數據集的代碼:

df <- data.frame(id = as.factor(c(1,1,1,2,2,3,4,4)),
             partner = c(1,2,3,1,2,1,1,2),
             kiss = as.factor(c("Yes", "No", "No", "No", "No", "Yes", "Yes", "No")))

  id partner kiss
1  1       1  Yes
2  1       2   No
3  1       3   No
4  2       1   No
5  2       2   No
6  3       1  Yes
7  4       1  Yes
8  4       2   No

我想在這個數據集中創建一個新的因子變量,指示該人(由'id變量表示)是否從未親吻過他們的任何“伙伴”。 換句話說,如果這個人與他們的任何一個伙伴有一個吻,那么新的變量將表示“是” - 他們從未與任何伴侶發過吻。 這是我認為應該是這樣的:

  id partner kiss neverkiss
1  1       1  Yes        No
2  1       2   No        No
3  1       3   No        No
4  2       1   No       Yes
5  2       2   No       Yes
6  3       1  Yes        No
7  4       1  Yes        No
8  4       2   No        No

理想情況下,我想找到一種方法來創建這個變量而不重塑數據集。 我也更喜歡使用dplyr包。 到目前為止,我已經考慮過使用group_by和mutate函數來創建這個變量。 但是,我不確定我可以使用哪些輔助函數來創建我的特定變量。 我對dplyr包之外的其他想法持開放態度,但這對我來說是一等獎。

這應該做到這一點

require(dplyr)

df <- data.frame(id = as.factor(c(1,1,1,2,2,3,4,4)),
             partner = c(1,2,3,1,2,1,1,2),
             kiss = as.factor(c("Yes", "No", "No", "No", "No", "Yes", "Yes", "No")))

df_new <- df %>% 
   group_by(id) %>% 
   mutate("neverkiss" = {if (any(kiss == "Yes")) "No" else "Yes"})

df_new

如果新列應包含您必須先ungroup因子

df_new <- df %>% 
   group_by(id) %>% 
   mutate("neverkiss" = {if (any(kiss == "Yes")) "No" else "Yes"}) %>% 
   ungroup() %>% 
   mutate("neverkiss" = as.factor(neverkiss))

class(df_new$neverkiss)
[1] "factor"

原因是因素無法合並:

a <- as.factor(c("Yes", "Yes", "Yes"))
b <- as.factor(c("No", "No", "No")) 

c(a, b) # meaningless

由於分組仍處於活動狀態,因此mutate基本上將向量neverkiss構建為每個id (組)的向量組合,這導致僅一個級別的向量(在這種情況下為“否”)。

我們也可以用data.table

library(data.table)
setDT(df)[, neverkiss := if(any(kiss=="Yes")) "No" else "Yes" , id]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM