【问题标题】:tidyr use separate_rows over multiple columnstidyr 在多列上使用单独的行
【发布时间】:2017-02-16 18:49:39
【问题描述】:

我有一个 data.frame,其中一些单元格包含逗号分隔值的字符串:

d <- data.frame(a=c(1:3), 
       b=c("name1, name2, name3", "name4", "name5, name6"),
       c=c("name7","name8, name9", "name10" ))

我想将每个名称拆分为自己的单元格的那些字符串分开。这很容易使用

tidyr::separate_rows(d, b, sep=",") 

如果一次完成一列。但我不能同时对“b”和“c”两个列执行此操作,因为它要求每个字符串中的名称数量相同。而不是写

tidyr::separate_rows(d, b, sep=",") 
tidyr::separate_rows(d, c, sep=",") 

有没有办法在单行中做到这一点,例如申请?类似的东西

apply(d, 2, separate_rows(...)) 

不确定如何将参数传递给separate_rows() 函数。

【问题讨论】:

    标签: r apply tidyr


    【解决方案1】:

    您可以使用管道。请注意,sep = ", " 会被自动检测到。

    d %>% separate_rows(b) %>% separate_rows(c)
    #   a     b      c
    # 1 1 name1  name7
    # 2 1 name2  name7
    # 3 1 name3  name7
    # 4 2 name4  name8
    # 5 2 name4  name9
    # 6 3 name5 name10
    # 7 3 name6 name10
    

    注意:使用 tidyr 版本 0.6.0,其中 %&gt;% 运算符包含在包中。


    更新:使用@doscendodiscimus 注释,我们可以使用for() 循环并在每次迭代中重新分配d。这样我们就可以拥有任意多的列。我们将使用列名的字符向量,因此我们需要切换到标准评估版本separate_rows_

    cols <- c("b", "c")
    for(col in cols) {
        d <- separate_rows_(d, col)
    }
    

    它给出了更新的d

      a     b      c
    1 1 name1  name7
    2 1 name2  name7
    3 1 name3  name7
    4 2 name4  name8
    5 2 name4  name9
    6 3 name5 name10
    7 3 name6 name10
    

    【讨论】:

    • 是的,我可以为每一行写同一行,但有没有办法为 n 列执行此操作?如果您有 10 列或更多列,它会变得乏味。关于 cols 参数,如果同时包含两列,则会出现错误。
    • @user23413,如果您想坚持使用tidyr,可以尝试像for(col in c("b", "c")) d &lt;- separate_rows_(d, col, sep = ",") 这样的循环
    • @docendodiscimus - 你想发布那个吗?我同意这是要走的路。
    • @RichScriven,不,如果您喜欢,可以将其添加到您的帖子中:)
    • 也可以试试这个变体:d %&gt;% Reduce(f = separate_rows_, x = c("b", "c"))
    【解决方案2】:

    这是使用splitstackshape::cSplitzoo::na.locf 的替代方法。

    library(splitstackshape)
    library(zoo)
    
    df <- cSplit(d, 1:ncol(d), "long", sep = ",")
    na.locf(df[rowSums(is.na(df)) != ncol(df),])
    #    a     b      c
    #1:  1 name1  name7
    #2:  1 name2  name7
    #3:  1 name3  name7
    #4:  2 name4  name8
    #5:  2 name4  name9
    #6:  3 name5 name10
    #7:  3 name6 name10
    

    【讨论】:

      猜你喜欢
      • 2019-01-26
      • 1970-01-01
      • 2021-07-26
      • 2019-11-12
      • 2017-07-16
      • 2020-06-18
      • 2017-08-25
      • 2018-04-13
      • 2021-11-19
      相关资源
      最近更新 更多