按组,将值与特定值匹配

我有一个数据集,其中包含针对特定决策d的每个选民v的投票结果r.我的数据如下所示:

d <- c(1,1,1,1,2,2,2,2,3,3,3,4,4,4,4)
v <- c(6,7,8,9,6,7,8,9,6,7,9,6,7,8,9)
r <- c(y,y,n,n,n,n,n,n,y,y,y,y,y,a,y)
df <- data.frame(d,v,r)

并非每个选民都在每次选举中投票.我想做的是看看其他选民是否与特定的选民进行同样的呼叫(假设v == 8).通常我会使用dplyr:

df %>% group_by(d) %>% mutate(like8 = ifelse(r == r[v == 8], 1, 0))

我所遇到的问题是,特定的选民v == 8没有对每个决定进行记录投票(这与投票的弃权不同,后者被记录).因此,我得到以下错误.

Error in mutate_impl(.data, dots) :
Column like8 must be length 3 (the group size) or one, not 0

到目前为止我所做的是编写ifelse和循环的组合以解决这个问题.

with(df,
    for (i in unique(d)) {
        if(8 %in% v){ 
            for (j in r[d == i]) {
            df$like8[d == i & r == j] <- ifelse(j == r[v == 8], 1, 0)
                                 }
                    } else {
            for (j in r[d == i]){
            df$like8[d == i & r == j] <- NA
                                } 
                           }
                         }
)

– 注意:我从来没有正式接受过’好’编程惯例的指导,所以我的支架位置可能不清楚,并且可以接受建议.

我遇到的问题是我的实际数据集有超过500,000个观测值,这非常慢.我已经看到使用data.table的here解决方案,当值没有丢失时,但我不理解data.table足以知道如何让它适用于我的情况.

最佳答案 试试这个:

df %>% 
    group_by(d) %>% 
    mutate(
      like8 = {
        if (sum(v == 8) > 0) as.numeric(r == r[v == 8])
        else NA
      }
    )

它将测试包装在if / else语句中,检查是否存在选民8.as.numeric语句等同于您编写的语句,但是当您的响应为1/0时应该更快.

点赞