在R中连接具有相似名称的多行
Concatenating multiple rows with similar names in R
我有一个包含 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 是文件名。我能做什么?
一种选择是使用 dplyr
中的 select_
,然后使用 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
tidyr
和 dplyr
的一种方式:
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"))
像这样使用do.call
和paste0
,使用如下数据集(使用@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
我有一个包含 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 是文件名。我能做什么?
一种选择是使用 dplyr
中的 select_
,然后使用 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
tidyr
和 dplyr
的一种方式:
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"))
像这样使用do.call
和paste0
,使用如下数据集(使用@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