如何识别所有行的至少一列中具有值的 ID?

Posted

技术标签:

【中文标题】如何识别所有行的至少一列中具有值的 ID?【英文标题】:How to identify an ID with values in at least one column for all rows? 【发布时间】:2021-03-11 21:00:25 【问题描述】:

我有一个带有 cloumns 的 data.frame:id、name、year、rop、des、cax、pcld。

我需要在至少一列(ropdes strong>、cax e pcld)适用于所有年份(2014、2015、2016、2017)。之后,我需要确定多年来已停产的那些(例如:2014 = 1、2015 = 1、2016 = 0)。

因此,作为第一步,我考虑转置 data.frame,使其看起来像这样:

 id | name | conta | 2014 | 2015 | 2016 | 2017
 
 3243 | teste| rop   |   1  |   0  |  0    | 1
 3243 | teste| des   |   0  |   1  |  0    | 0
 3243 | teste| cax   |   0  |   0  |  1    | 0
 3243 | teste| pcld  |   0  |   0  |  0    | 0

在下一步中,将识别 ID“3243”。它在所有年份(列)中至少有一个值“1”。

我一直在尝试转置:

library(magrittr)

dados   %>% dplyr::select(id, name, year, rop, des, cax, pcld) %>% 
            tidyr::pivot_longer(
                                 cols = -c('id', 'name'),
                                 names_to = 'Conta'

                                ) 
 

数据:

structure(list(
    id = c(1111, 1111, 1111, 1111, 22222,22222, 22222, 22222, 33333, 33333,3243,3243,3243,3243), 
    name = c("empresa", "empresa", "empresa", "empresa","firma", "firma", "firma", "firma", "loja", "loja","teste","teste","teste","teste"), 
    year = c(2014, 2015, 2016, 2017, 2014, 2015, 2016, 2017, 2014,2015,2014, 2015, 2016, 2017),
    rop = c(1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1), 
    des = c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), 
    cax = c(1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0), 
    pcld = c(1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0)), 
    row.names = c(NA,14L), class = "data.frame")

有更好的方法吗?

【问题讨论】:

您的示例 dput 没有 3243 你需要names(which(sapply(split(dados[4:7], dados$id, drop = TRUE), function(x) all(rowSums(x) > 0)))) @akun,刚刚将 3243 添加到我的输入中。 根据新数据,我得到[1] "3243" "3333" "22222" "33333"满足条件。可能是你有一个错字,即2222 而不是222223333 而不是33333 @akun,我修好了。 【参考方案1】:

试试这个:

 df %>% group_by(id,year) %>% 
        rowwise() %>%
        mutate(C=max(rop,des,cax,pcld)) %>%
        group_by(id) %>%
        filter(sum(C)==4) %>% 
        select(-C) %>%
        ungroup

【讨论】:

【参考方案2】:

如果我们想要将 'id' 子集化,其中从 'rop' 到 'pcld' 的列中至少有一个在其所有行的列中都为 1,然后通过创建按 'id' 和 filter 进行分组一个带有rowSums 的逻辑向量,并用all 包装

library(dplyr)
dados %>% 
   group_by(id) %>% 
   filter(all(rowSums(select(cur_data(), rop:pcld)) > 0)) %>%
   ungroup

或者另一个选项是if_anydplyr 版本1.0.4)和all

dados %>%
    group_by(id) %>%
    filter(all(if_any(rop:pcld, as.logical)))

if_any 在列 roppcld 上循环,将二进制转换为逻辑 (as.logical),如果一行的任何列有 1,则返回 TRUE/FALSE 作为向量,然后将逻辑向量包装为all 以便它返回单个 TRUE(当所有行的任何列至少有一个 1 时)或 FALSE(当任何行的所有列都没有 1 时)来子集 'id'

【讨论】:

以上是关于如何识别所有行的至少一列中具有值的 ID?的主要内容,如果未能解决你的问题,请参考以下文章

如何查询仅出现特定列中具有最高值的行的行?

返回除一列中具有重复 ID 的行之外的所有列

如何在R中的一列中添加具有不同值的新行

如何使用实体框架中的 DBContext 获取在另一列中具有重复数据的所有 ID?

SQL 选择以消除在下一列中具有 2 个其他值的重复值

如何在 MySQL 中加快一列中所有值的简单更新