【问题标题】:How to delete rows in R, which contains the same "set" of data within a column如何删除 R 中的行,该行在列中包含相同的数据“集”
【发布时间】:2018-05-08 00:57:19
【问题描述】:

我有一个包含两列 liftskill.set 的数据数据框。在skill.set 中,包含一串以逗号分隔的技能。例如,可能有一个字符串“Excel, PowerPoint”和另一个“PowerPoint, Excel”。这两个观察正在捕获相同的数据,我只想保留其中一个(具有最高提升的那个)。如果不将每个字符串天真地转换为元素用逗号分隔的向量,然后编写一个 for 循环将每个 skill.set 数据与彼此 skill.set 数据进行比较,我想不出一种有效的方法。

示例数据框:

df = structure(list(lift = c(5.71421247789905, 4.65329289252856, 5.87820023244231, 
21.1815668998877), skill.set = c("JavaScript,Microsoft.Excel..MS.Excel.,Microsoft.Word,Python,Microsoft.PowerPoint", 
"Microsoft.PowerPoint,Microsoft.Word,Python,SQL,Microsoft.Excel..MS.Excel.", 
"Microsoft.Excel..MS.Excel.,Microsoft.Word,Python,SQL,Microsoft.PowerPoint", 
"Analytics...Text.Mining,Natural.Language.Processing,Python")), .Names = c("lift", 
"skill.set"), row.names = 239:242, class = "data.frame")

所需的数据框:

structure(list(lift = c(5.71421247789905, 5.87820023244231, 21.1815668998877
), skill.set = c("JavaScript,Microsoft.Excel..MS.Excel.,Microsoft.Word,Python,Microsoft.PowerPoint", 
"Microsoft.Excel..MS.Excel.,Microsoft.Word,Python,SQL,Microsoft.PowerPoint", 
"Analytics...Text.Mining,Natural.Language.Processing,Python")), .Names = c("lift", 
"skill.set"), row.names = c(239L, 241L, 242L), class = "data.frame")

【问题讨论】:

    标签: r string vector duplicates set


    【解决方案1】:

    我们可以做到以下几点:

    df[!duplicated(sapply(strsplit(df$skill.set, ","), function(x) 
        paste0(sort(x), collapse = ","))), ]
    #         lift
    #239  5.714212
    #240  4.653293
    #242 21.181567
    #                                                                           skill.set
    #239 JavaScript,Microsoft.Excel..MS.Excel.,Microsoft.Word,Python,Microsoft.PowerPoint
    #240        Microsoft.PowerPoint,Microsoft.Word,Python,SQL,Microsoft.Excel..MS.Excel.
    #242                       Analytics...Text.Mining,Natural.Language.Processing,Python
    

    解释:在","上拆分df$skill.set中的条目,然后排序条目并连接;只保留不重复的条目。


    更新

    要只保留lift 值最大的行,我们可以使用aggregate

    setNames(aggregate(
        lift ~ sapply(strsplit(skill.set, ","), function(x) paste0(sort(x), collapse = ",")),
        df,
        max), rev(names(df)))
    #1                       Analytics...Text.Mining,Natural.Language.Processing,Python
    #2 JavaScript,Microsoft.Excel..MS.Excel.,Microsoft.PowerPoint,Microsoft.Word,Python
    #3        Microsoft.Excel..MS.Excel.,Microsoft.PowerPoint,Microsoft.Word,Python,SQL
    #       lift
    #1 21.181567
    #2  5.714212
    #3  5.878200
    

    【讨论】:

    • 我现在看到了逻辑,很好的解释。此方法将始终保留第一个唯一集并删除重复的集。但是如果第二组的提升值更高(这是我想要保留的那一组)怎么办?
    • @KevinSun 对于它仍然有价值的东西,我使用aggregate 添加了一个基本 R 解决方案。
    【解决方案2】:

    这是使用dplyrtidyr 的另一种解决方案。

    df %>%
      separate_rows(skill.set, sep = ",") %>%
      group_by(lift) %>%
      arrange(skill.set) %>%
      mutate(id = row_number()) %>%
      spread(id, skill.set) %>%
      unite(skill.set, 2:6, sep = ",") %>%
      group_by(skill.set) %>%
      summarise_at(vars(lift), max)
    

    您可以通过将max 更改为您喜欢的任何内容来决定要保留哪个lift。另外,根据前面的spread 生成的列号更改2:6

    【讨论】:

    • 非常恰当地使用separate_rows
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2022-11-03
    • 2023-02-04
    • 2019-11-25
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多