【问题标题】:all group members but the current row除当前行外的所有组成员
【发布时间】:2017-03-31 21:01:10
【问题描述】:

我有一个分组数据框,如下所示:

df <- data.frame(group = rep(1:4, each=3),
                 lets = rep(LETTERS[1:4], times=3))

对于每一行,我现在想识别同一组中的所有lets,而不是行本身的lets。使用 dplyr 我可以得到 all lets 因此:

df %>%
  group_by(group) %>%
  mutate(all_lets_in_group = paste(lets, collapse=','))

但是如何从我输入到paste() 的内容中排除当前行的lets

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    这个任务的目的不是很清楚,因此代码的清晰度也会受到影响,但仍然:

    library(tidyverse)
    
    df %>%
      group_by(group) %>%
      mutate(
        all_lets_in_group = lets %>% 
          map(function(l) setdiff(., l)) %>%
          map_chr(function(x) paste(x, collapse=',')))
    

    使用集合操作setdiff从组的集合中减去purrr::map提供的当前字母,然后用paste重新格式化向量列表并作为字符向量返回。

    【讨论】:

    • 您可以使用公式清理代码并获得更好的高尔夫成绩。 map(~setdiff(lets, .x))map_chr(~paste(.x, collapse=','))
    • @JakeKaupp 我可能做错了,但作为上述公式的替代品似乎不起作用。
    【解决方案2】:

    不确定dplyr 解决方案,但您可以使用lapply

    df$all_lets_in_group <- lapply(1:nrow(df), function(x) 
        paste(with(df, lets[group == group[x] & lets != lets[x]]), collapse = ','))
    

    【讨论】:

      【解决方案3】:

      另一种使用avesapplysetdiff 的基本R 方法

      ave(df$lets, df$group,
          FUN=function(i) sapply(i, function(j) paste(setdiff(i, j), collapse=",")))
       [1] "B,C" "A,C" "A,B" "A,B" "D,B" "D,A" "D,A" "C,A" "C,D" "C,D" "B,D" "B,C"
      

      【讨论】:

        猜你喜欢
        • 2021-06-24
        • 2016-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多