【问题标题】:Coalesce columns based on pattern in R [duplicate]基于R中的模式合并列[重复]
【发布时间】:2019-11-08 14:22:42
【问题描述】:

我在 R 中合并了数据集,每个数据集可能对相同的数据使用不同的列名。我需要使用正则表达式来识别我需要组合的列的名称,然后通过合并运行该列名列表。

我知道正确的正则表达式来标识我的列,并且我知道如何手动将列名写入合并函数以合并这些列,但我不知道如何自动合并使用正则表达式标识的列。

sample = data.frame("PIDno" = c('a', NA, NA), "PINID" = c(NA, 'b', NA), "ParcelId" = c(NA, NA, 'c'))

PID_search = paste("sample$",grep("*PID*|*PIN*|*PARCEL*",colnames(sample),ignore.case = TRUE, value = TRUE),sep = "")

sample$PID_combine = coalesce(sample$'PIDno',
                              sample$'PINID',
                              sample$'ParcelId')

【问题讨论】:

    标签: r regex dplyr coalesce


    【解决方案1】:

    我们可以使用tidyverse。选定的列转换为charactermutate_at,然后coalesce mutate 中的那些列

    library(tidyverse)
    sample %>%
        mutate_at(vars(matches("PID|PIN|Parcel")), as.character) %>% 
        mutate(new = coalesce(!!! select(., matches("PID|PIN|Parcel"))))
    #    PIDno PINID ParcelId new
    #1     a  <NA>     <NA>   a
    #2  <NA>     b     <NA>   b
    #3  <NA>  <NA>        c   c
    

    【讨论】:

    • 这对我有用,但我不确定为什么在合并中需要否定。我希望它是new = coalesce(select(., matches("PID|PIN|Parcel"))),但使用类似的东西会让我的列保持不变。
    • @KevinMc 这不是 tidyverse 中的否定。评估函数为!!!!!
    【解决方案2】:

    我会这样做。

    • (a) 不要将"sample$PIDno" 作为一个字符串——那是非常没用的。只需将列名作为字符串获取即可。
    • (b) 我们将创建一个单独的函数,在数据框中的所有列上调用coalesce。这很好,很容易写,然后我们可以......
    • (c) 对要合并的列子集调用coalesce_df 函数。根据列名向量对数据框进行子集化很容易,因此我们简化了第一步,并添加了两个额外的简单步骤来获得结果。

    对于您的示例数据,这些列都是factors,具有不同的级别。无法按原样合并这些内容,因此我添加了 lapply(..., as.character) 以首先将所有内容转换为字符。如果您的真实数据不是factor 类,那么您可以跳过该步骤。

    cols = grep("*PID*|*PIN*|*PARCEL*",colnames(sample),ignore.case = TRUE, value = TRUE)
    
    coalesce_df = function(df) {
      do.call(coalesce, df)
    }
    
    coalesce_df(lapply(sample[cols], as.character))
    # [1] "a" "b" "c"
    

    如果您想在 dplyr 管道中完成这项工作,我建议您这样做(或者查看 akrun 的答案以获得更惯用的内容)。

    sample %>%
      mutate_at(vars(one_of(cols)), as.character) %>%
      mutate(PID_combine = coalesce_df(.[cols]))
    #   PIDno PINID ParcelId PID_combine
    # 1     a  <NA>     <NA>           a
    # 2  <NA>     b     <NA>           b
    # 3  <NA>  <NA>        c           c
    

    【讨论】:

      【解决方案3】:

      我可能找错了树,但coalesce() 函数的约定是它返回参数列表中的第一个非NA 值,从左到右。所以,如果你使用下面的代码:

      sample$PID_combine = coalesce(sample$PIDno, sample$PINID, sample$ParcelId)
      

      那么行为将是首先返回PIDno,如果该值不是NA,然后是PINID,然后是ParcelID,按此顺序。

      对于您在问题中提供的示例输入数据,PID_combine 的值将是 ['a', 'b', 'c']

      【讨论】:

      • 我也可能是错的,但我阅读 OP 时希望以某种方式动态将列名传递给coalesce
      • 给出的代码不够清晰,我无法更新我的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 2015-01-17
      • 2016-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多