【问题标题】:Concatenating multiple rows with similar names in R在R中连接具有相似名称的多行
【发布时间】:2018-02-18 00:22:02
【问题描述】:

我有一个带有 30 个变量的数据框 db1。在这 30 个中,有 10 个具有连续名称 - X1、X2、....X10。所有这些 X 变量都是字符。我想连接所有这些。所以我当然可以做

db1$new <- paste(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10)

但是,这并不好玩,而且如果我有一个包含不同数量 X 变量的新文件,则此代码将不起作用。所以,我需要一些使用变量名连接的方法。我试过了

zz1 <- paste(grep('^X',names(db1), value = TRUE))
zz2 <- paste("db1$",zz1,sep="",collapse = ",")

第二个语句是获取逗号分隔的变量名。然后我尝试使用

进行合并
db1$new <- paste(db1$Terms,zz2,collapse = ","))

这不起作用,因为 R 不理解 zz2 是文件名。我能做什么?

【问题讨论】:

    标签: r string-concatenation


    【解决方案1】:

    一种选择是使用select_ 中的dplyr,然后使用apply

    #data
    db1 <- data.frame(id = 1:2, x1 = c("a", "b"), x2 = c("a", "b"),
                      x3 = c("a", "b"))
    
    library(tidyverse)
    
    db1$new <- db1 %>% 
    select_(.dots = grep("^x\\d+",names(db1), value = T)) %>%
    apply(1,paste,collapse="") 
    
    db1
    # Result
    #  id x1 x2 x3 new
    #1  1  a  a  a aaa
    #2  2  b  b  b bbb
    

    【讨论】:

      【解决方案2】:

      tidyrdplyr 的一种方式:

      library(dplyr)
      library(tidyr)
      
      unite(db1, "var", starts_with("x"), sep = "")
      
      #   var z1
      # 1 aaa  a
      # 2 bbb  b
      

      这将unite starts_with "x" 的任何列并将结果存储在名为 var 的变量中。

      如果数据的结构使得存在其他不感兴趣的以“x”开头的变量(例如“xvar”)并且不应连接,那么您可以将 starts_with 替换为 matches 并使用常用表达。感谢 MKR 的建议:

      unite(db1, "var", matches("^x\\d+"), sep = "")
      
      #   var z1 xvar
      # 1 aaa  a    a
      # 2 bbb  b    b
      

      数据:

      db1 <- data.frame(x1 = c("a", "b"), 
                        x2 = c("a", "b"),
                        z1 = c("a", "b"),
                        x3 = c("a", "b"))
      

      【讨论】:

      • 善用starts_withunitie。我可以看到改进的范围。 starts_with 将考虑所有列,如 xaxname 等。但也许 OP 的意图是只考虑 x1x2 等。
      • 好点。在这种情况下,我们可以使用你的正则表达式将starts_with 替换为matches("x\\d+")
      • 当然,我在你提到它的那一刻就更新了它。只是在看正则表达式时分心了。
      • 我想知道将x\\d+ 更改为^x\\d+ 是否会更好?这样lax2 之类的东西就不会被接收到。还注意到 OP 在他的grep 电话中有这个。
      【解决方案3】:

      使用do.callpaste0,像这样,使用如下数据集(使用@MKR 数据):

      df <- structure(list(id = 1:2, X1 = c("a", "b"), X2 = c("a", "b"), 
              X3 = c("a", "b")), .Names = c("id", 
          "X1", "X2", "X3"), row.names = c(NA, -2L), class = "data.frame")
      
      df$pastecol = do.call("paste0",df[,grep("^X\\d+$",names(df))])
      

      输出

      #> df$pastecol = do.call("paste0",df[,grep("^X\\d+$",names(df))])
      #> df
      #  id X1 X2 X3 pastecol
      #1  1  a  a  a      aaa
      #2  2  b  b  b      bbb
      

      【讨论】:

        猜你喜欢
        • 2018-11-20
        • 1970-01-01
        • 1970-01-01
        • 2019-12-27
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 2021-08-29
        相关资源
        最近更新 更多