基于R中的另一列数据框找到一列的共同值

Posted

技术标签:

【中文标题】基于R中的另一列数据框找到一列的共同值【英文标题】:find common values of a column based on group of another a column of data frame in R 【发布时间】:2021-12-29 06:01:17 【问题描述】:

我有这样的数据框:

df<-tibble(id=c("ls1","ls1","ls1","ls2","ls2","ls3","ls5","ls5","ls10","ls10","ls14"),
               target=c("A","A","B","G","H","A","B","B","G","HA","B"))

我想在 id 组内以及在 id 变量组之间的目标列中列出一个常见值。结果可能如下表所示:

res<-tibble(id=c("ls1","ls1","ls1","ls2","ls2","ls3","ls5","ls5","ls10","ls10","ls14"),
            target=c("A","A","B","G","H","A","B","B","G","HA","B"),
            withinGroup=c(T,T,F,F,F,F,F,T,T,F,F),
            numberofRepwithinGroup=c(2,2,1,1,1,1,1,2,2,1,1),
            betweenGroups=c(T,T,T,T,F,T,T,T,T,F,T),
            numberofRepbetweenGroups=c(2,2,3,2,0,3,3,3,2,0,3))

知道怎么做吗?

【问题讨论】:

【参考方案1】:

你可以用几个mutate()

library(dplyr)

df |>
  # first group by
  group_by(id, target) |>
  # add the within columns
  mutate(numberofRepwithinGroup = length(target),
         withinGroup            = ifelse(numberofRepwithinGroup > 1,T,F)) |> 
  # second group by
  group_by(target) |>
  # add the between columns
  mutate(numberofRepbetweenGroups = ifelse(n_distinct(id) == 1, 0, n_distinct(id)),
         betweenGroups            = ifelse(numberofRepbetweenGroups  > 0,T,F)) |>
   # reorder columns
  select(id,target, withinGroup, numberofRepwithinGroup, betweenGroups, numberofRepbetweenGroups
  ) |> 
  # remove useless grouping
  ungroup()

# A tibble: 11 x 6
   id    target withinGroup numberofRepwithinGroup betweenGroups numberofRepbetweenGroups
   <chr> <chr>  <lgl>                        <int> <lgl>                            <dbl>
 1 ls1   A      TRUE                             2 TRUE                                 2
 2 ls1   A      TRUE                             2 TRUE                                 2
 3 ls1   B      FALSE                            1 TRUE                                 3
 4 ls2   G      FALSE                            1 TRUE                                 2
 5 ls2   H      FALSE                            1 FALSE                                0
 6 ls3   A      FALSE                            1 TRUE                                 2
 7 ls5   B      TRUE                             2 TRUE                                 3
 8 ls5   B      TRUE                             2 TRUE                                 3
 9 ls10  G      FALSE                            1 TRUE                                 2
10 ls10  HA     FALSE                            1 FALSE                                0
11 ls14  B      FALSE                            1 TRUE                                 3

【讨论】:

不应该将 |&gt; 替换为 %&gt;% 吗? 从 R >4.1 中引入了 |> 基本运算符,非常类似于 magrittr 管道 %>%。如果您可以更换它并且它会起作用。 我无法通过此代码复制 res 表,它为 repwithin 组的所有值数量提供 11,为 repbetweengroup 的所有数量值提供 6,是否可以使用此代码从我的问题中生成确切的 res ? 同样@s__ :-) 确认这在 OP 提供的样本数据上 100% 有效并重现输出。 +1。 我发现了问题,plyr 包已加载到我的环境中,导致我得到不同的结果。对不起大家,非常感谢你们【参考方案2】:

这是一个选项

library(dplyr)
get_reps <- function(x) as.numeric(table(x)[match(x, names(table(x)))] - 1)
df %>%
    group_by(id) %>%
    mutate(
        withinGroup = duplicated(target) | duplicated(target, fromLast = T),
        numberofRepwithinGroup = get_reps(target)) %>%
    ungroup() %>%
    mutate(
        betweenGroups = duplicated(target) | duplicated(target, fromLast = T),
        numberofRepbetweenGroups = get_reps(target))
## A tibble: 11 x 6
#   id    target withinGroup numberofRepwithinGroup betweenGroups numberofRepbetweenGroups
#   <chr> <chr>  <lgl>                        <dbl> <lgl>                            <dbl>
# 1 ls1   A      TRUE                             1 TRUE                                 2
# 2 ls1   A      TRUE                             1 TRUE                                 2
# 3 ls1   B      FALSE                            0 TRUE                                 3
# 4 ls2   G      FALSE                            0 TRUE                                 1
# 5 ls2   H      FALSE                            0 FALSE                                0
# 6 ls3   A      FALSE                            0 TRUE                                 2
# 7 ls5   B      TRUE                             1 TRUE                                 3
# 8 ls5   B      TRUE                             1 TRUE                                 3
# 9 ls10  G      FALSE                            0 TRUE                                 1
#10 ls10  HA     FALSE                            0 FALSE                                0
#11 ls14  B      FALSE                            0 TRUE                                 3

【讨论】:

我使用了这段代码,但它对 numberofRepwithinGroup 和 numberofRepbetweenGroups 变量给出了类似的结果?!! 我无法复制。当我使用您的示例数据时,我完全重现了您的预期输出。你是说你无法重现这个?或者您是说您的更大/实际数据集存在问题?如果是后者,那么显然我们在问题陈述中遗漏了一些东西。 我无法重现示例数据集的结果。由于组内和组间列的结果是相同的。 @minoo 我看到你对我的解决方案和 Maurits Evers 解决方案有问题。我可以确认 Maurits Evers one 可以使用您发布的数据 - 并让我振作起来-。 @minoo 在您的数据或 R 环境中一定有其他东西会搞砸。尝试将 R 重新启动到干净的环境中;然后复制并粘贴您自己的代码和此处提供的解决方案。他们将 100% 重现您的预期输出。然后寻找您的实际数据与您发布的数据之间的差异。

以上是关于基于R中的另一列数据框找到一列的共同值的主要内容,如果未能解决你的问题,请参考以下文章

如何根据R中的另一列获取一列的平均值

如何根据 PySpark 数据框的另一列中的值修改列? F.当边缘情况

R:基于一个列的值存在于另一列中,生成虚拟变量

基于针对另一列的参考表更新 Pandas 数据框列的问题

如何将一列的列值组合到 MySQL 中的另一列中?

Groupby 和 collect_list 基于 PySpark 中的另一列维护顺序