将数据帧中的两列或多列合并为具有新名称的新列

Combine two or more columns in a dataframe into a new column with a new name

提问人:user2654764 提问时间:8/8/2013 最后编辑:Andryuser2654764 更新时间:7/10/2022 访问量:639153

问:

例如,如果我有这个:

n = c(2, 3, 5) 
s = c("aa", "bb", "cc") 
b = c(TRUE, FALSE, TRUE) 
df = data.frame(n, s, b)

  n  s     b
1 2 aa  TRUE
2 3 bb FALSE
3 5 cc  TRUE

那么,如何将这两列合并到一个新列中,使其如下所示:nsx

  n  s     b     x
1 2 aa  TRUE  2 aa
2 3 bb FALSE  3 bb
3 5 cc  TRUE  5 cc
数据帧 多列 R-FAQ

评论


答:

170赞 mnel 8/8/2013 #1

用。paste

 df$x <- paste(df$n,df$s)
 df
#   n  s     b    x
# 1 2 aa  TRUE 2 aa
# 2 3 bb FALSE 3 bb
# 3 5 cc  TRUE 5 cc

评论

0赞 Chetan Arvind Patil 10/6/2017
.@thelatemail - 如何使用 ?在上面的示例中,列的数据应为 、then 和 。paste()x2-aa3-bb5-cc
10赞 Chetan Arvind Patil 10/7/2017
.@thelatemail - 这对我有用:paste(df$n,df$s,sep="-")
4赞 Cina 8/11/2018
如果列有 NA 值,如何省略 NA?(我不喜欢看看是否s3 NAdf$s[2]=NA)
16赞 Ferroao 12/6/2016 #2

NA 的一些示例以及使用 apply 删除它们

n = c(2, NA, NA) 
s = c("aa", "bb", NA) 
b = c(TRUE, FALSE, NA) 
c = c(2, 3, 5) 
d = c("aa", NA, "cc") 
e = c(TRUE, NA, TRUE) 
df = data.frame(n, s, b, c, d, e)

paste_noNA <- function(x,sep=", ") {
gsub(", " ,sep, toString(x[!is.na(x) & x!="" & x!="NA"] ) ) }

sep=" "
df$x <- apply( df[ , c(1:6) ] , 1 , paste_noNA , sep=sep)
df

评论

0赞 malajisi 3/12/2019
@Ferroao 谢谢,你救了我的命。请在 DF$X <应用之前移动paste_noNA函数。
54赞 Little Bee 2/28/2017 #3

要插入分隔符:

df$x <- paste(df$n, "-", df$s)

评论

1赞 Chetan Arvind Patil 10/6/2017
.@LittleBee - 这会在两个数据之间添加一个空格。例如,最终输出如下所示:而不是 .是否可以删除此多余空间?A - BA-B
9赞 Chetan Arvind Patil 10/7/2017
.@LittleBee - 这对我有用:paste(df$n,df$s,sep="-")
5赞 Ferroao 11/3/2017
使用 paste0 而不是 paste
3赞 Cath 3/27/2019
这不会给出所需的输出:OP 要求在元素之间留一个空格,而不是另一个分隔符(顺便说一句,最好将其作为参数......然而,另一个答案比你早了将近 4 年,完美地回答了这个问题。sep
14赞 yanes 4/8/2017 #4

我们可以使用 paste0

df$combField <- paste0(df$x, df$y)

如果您不希望在连接字段中引入任何填充空间。如果您计划将组合字段用作表示两个字段组合的唯一 ID,这将更有用。

20赞 sbha 3/11/2018 #5

用:dplyr::mutate

library(dplyr)
df <- mutate(df, x = paste(n, s)) 

df 
> df
  n  s     b    x
1 2 aa  TRUE 2 aa
2 3 bb FALSE 3 bb
3 5 cc  TRUE 5 cc

评论

2赞 zx8754 3/27/2019
不,正如已经存在的答案一样,您使用的是粘贴,而不是突变
0赞 sbha 3/28/2019
我以为我是在演示如何将列组合为 .对不起,只是想提供帮助 - 我不会再污染网站并放弃未来的帖子。dplyr::mutate()
0赞 zx8754 3/28/2019
对不起,如果它被证明是粗鲁的。OP 的问题不是通过使用 mutate 来解决的,问题不是关于如何使用 dplyr,而是如何组合列值。我只是指出,他们需要粘贴而不是变异。如果我们想证明 dplyr 的正确方法是使用函数 unite
0赞 jdcode 2/13/2022
@zx8754,为什么 mutate 不正确,但 unite 是正确的?您分享的答案引用了 Uwe 和 UseR 的评论,但看起来这些评论已被删除。
28赞 Quentin Perrier 4/16/2018 #6

正如 Uwe 和 UseR 的评论中已经提到的,该格式的一般解决方案是使用命令:tidyverseunite

library(tidyverse)

n = c(2, 3, 5) 
s = c("aa", "bb", "cc") 
b = c(TRUE, FALSE, TRUE) 

df = data.frame(n, s, b) %>% 
  unite(x, c(n, s), sep = " ", remove = FALSE)

评论

2赞 Levi 4/3/2019
这个例子中的x是什么?
1赞 Vesanen 8/14/2020
@Levi,表示包含组合值的新列的名称。想想 dplyr 的:xmutatedf %>% dplyr::mutate(x = "your operations")
0赞 jdcode 2/13/2022
你能解释一下为什么 mutate 不正确但 unite 是正确的吗?我认为这已经在 Uwe 和 UseR 的评论中解释过,但我似乎找不到这些评论——我认为它们已被删除。谢谢!
8赞 avallecam 8/14/2018 #7

而不是

  • paste(默认空格),
  • paste0(强制包含 missing 作为字符)或NA
  • unite(限制为 2 列和 1 个分隔符),

我建议一个替代方案,既灵活,又更小心:paste0NAstringr::str_c

library(tidyverse)

# check the missing value!!
df <- tibble(
  n = c(2, 2, 8),
  s = c("aa", "aa", NA_character_),
  b = c(TRUE, FALSE, TRUE)
)

df %>% 
  mutate(
    paste = paste(n,"-",s,".",b),
    paste0 = paste0(n,"-",s,".",b),
    str_c = str_c(n,"-",s,".",b)
  ) %>% 

  # convert missing value to ""
  mutate(
    s_2=str_replace_na(s,replacement = "")
  ) %>% 
  mutate(
    str_c_2 = str_c(n,"-",s_2,".",b)
  )
#> # A tibble: 3 x 8
#>       n s     b     paste          paste0     str_c      s_2   str_c_2   
#>   <dbl> <chr> <lgl> <chr>          <chr>      <chr>      <chr> <chr>     
#> 1     2 aa    TRUE  2 - aa . TRUE  2-aa.TRUE  2-aa.TRUE  "aa"  2-aa.TRUE 
#> 2     2 aa    FALSE 2 - aa . FALSE 2-aa.FALSE 2-aa.FALSE "aa"  2-aa.FALSE
#> 3     8 <NA>  TRUE  8 - NA . TRUE  8-NA.TRUE  <NA>       ""    8-.TRUE

创建于 2020-04-10 由 reprex 软件包 (v0.3.0)

文档中的额外说明str_c

与大多数其他 R 函数一样,缺失值是“具有感染力的”:每当一个缺失值与另一个字符串组合时,结果将始终丢失。用于转换为str_replace_na()NA"NA"

评论

1赞 Axeman 3/28/2019
paste0(n,"-",s,".",b)并且完全相同,两者都使用默认分隔符,即空字符串。我也不知道为什么是“整洁”,你的意思是你不喜欢空格?str_c(n,"-",s,".",b)''paste
0赞 avallecam 1/21/2020
paste0并且不完全相同。看看这些链接:(1)rdocumentation.org/packages/stringr/versions/1.3.1/topics/str_c(2)stackoverflow.com/questions/53118271/...str_c
0赞 Axeman 1/21/2020
啊,我明白了!谢谢!它们的不同之处将是这个答案的一个很好的补充(文档也可以更明确!str_c
0赞 avallecam 4/10/2020
@Axeman感谢您的建议。我简化了答案,并添加了有关该问题的额外注释
6赞 Ben Ernest 4/15/2020 #8

还有其他很好的答案,但是如果您事先不知道列名或要连接的列数,以下内容很有用。

df = data.frame(x = letters[1:5], y = letters[6:10], z = letters[11:15])
colNames = colnames(df) # could be any number of column names here
df$newColumn = apply(df[, colNames, drop = F], MARGIN = 1, FUN = function(i) paste(i, collapse = ""))
1赞 Iyar Lin 7/10/2022 #9

我还想提出一种连接大量/未知列的方法。Ben Ernest 提出的解决方案在大型数据集上可能非常慢。

以下是我提出的解决方案:

# setup data.frame - Making it large for the time benchmarking
n = rep(c(2, 3, 5), 1000000)
s = rep(c("aa", "bb", "cc"), 1000000)
b = rep(c(TRUE, FALSE, TRUE), 1000000) 
df = data.frame(n, s, b)

# The proposed solution:
colNames = c("n", "s") # could be any number of column names here
df$x <- do.call(paste0, c(df[,colNames], sep=" "))

# running system.time on this yields:
# user  system elapsed 
# 1.861   0.005   1.865 

# compare with alternative method:
df$x <- apply(df[, colNames, drop = F], MARGIN = 1, 
                         FUN = function(i) paste(i, collapse = ""))
# running system.time on this yields:
# user  system elapsed 
#  16.127   0.147  16.304