如何将数据框中的两个或多个列组合成一个具有新名称的新列?

use*_*764 88 r multiple-columns dataframe r-faq

例如,如果我有这个:

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
Run Code Online (Sandbox Code Playgroud)

然后,我如何将两列n和s组合成一个名为x的新列,使其看起来像这样:

  n  s     b     x
1 2 aa  TRUE  2 aa
2 3 bb FALSE  3 bb
3 5 cc  TRUE  5 cc
Run Code Online (Sandbox Code Playgroud)

mne*_*nel 106

使用 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
Run Code Online (Sandbox Code Playgroud)

  • .@ thelatemail - 这对我有用:`paste(df $ n,df $ s,sep =" - ")` (6认同)
  • 如果`s`列的值为NA,你怎么能省略NA?(如果`df$s[2]=NA`,我不喜欢看到`3 NA`) (3认同)

Lit*_*Bee 25

__CODE__ 用于插入分隔符.

  • .@ LittleBee - 这对我有用:`粘贴(df $ n,df $ s,sep =" - ") (7认同)
  • 使用paste0而不是paste (5认同)
  • 这不会提供所需的输出:OP要求在元素之间留一个空格,而不是另一个分隔符(顺便说一下,最好将其作为`sep`参数来放置...)。另一个答案比您的答案早了将近四年,但是它可以完美地回答这个问题。 (3认同)

小智 10

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

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)
Run Code Online (Sandbox Code Playgroud)

  • 在这个例子中 x 是什么? (2认同)

Fer*_*oao 9

使用NA的一些示例及其删除

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
Run Code Online (Sandbox Code Playgroud)

  • 如果你想使用`tidyr`包重现原始问题的预期答案,这将是一个单行:`tidyr :: unite(df,x,n,s,sep ="",remove = FALSE) [,c(names(df),"x")]`.但是,我没有理由这样做,因为`df $ x < - paste(df $ n,df $ s)`更简单. (2认同)

sbh*_*bha 7

使用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
Run Code Online (Sandbox Code Playgroud)

  • 不,正如已经存在的答案一样,您使用的是 *paste*,而不是 *mutate*。 (2认同)

小智 5

我们可以使用paste0

df$combField <- paste0(df$x, df$y)
Run Code Online (Sandbox Code Playgroud)

如果您不想在连接字段中引入任何填充空间。如果您打算将组合字段用作代表两个字段组合的唯一ID,则此功能将更为有用。


ava*_*cam 5

代替

  • paste (不整洁),
  • paste0 (默认分隔符)或
  • unite (限于2列和1个分隔符),

我建议使用更灵活的替代方法: stringr::str_c

library("tidyverse")
df %>% mutate(x=str_c(n,"-",s,".",b))
#> # A tibble: 3 x 4
#>       n s     b     x         
#>   <dbl> <fct> <lgl> <chr>     
#> 1     2 aa    TRUE  2-aa.TRUE 
#> 2     3 bb    FALSE 3-bb.FALSE
#> 3     5 cc    TRUE  5-cc.TRUE 
Run Code Online (Sandbox Code Playgroud)


Ben*_*est 5

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

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 = ""))
Run Code Online (Sandbox Code Playgroud)