【问题标题】:combining r dataframe columns dynamically动态组合 r 数据框列
【发布时间】:2022-10-05 23:14:59
【问题描述】:

我有一个函数,用户在其中输入列和数据框的字符串向量作为参数,它返回带有新列的数据框,其中列的元素连接如下:

数据框:

df <- data.frame(x = c(\"A\",\"B\",\"C\",\"D\",\"E\"), y = c(\"1\",\"2\",\"3\",\"4\",\"5\"),
           z = c(\"Test1\",\"Test2\", \"Test3\",\"Test4\",\"Test5\"),
           w =c(\"B1\",\"B2\",\"B3\",\"B4\",\"B5\"))

如果用户将向量定义为vec &lt;- c(\"x\",\"y\"),则输出应为:

newcol <- function(df, vec){
  df <- df %>% mutate(newcolumn = paste(get(\"x\"),get(\"y\"), sep = \",\"))
  return (df)
}

newcol(df, vec)

  x y     z  w newcolumn
1 A 1 Test1 B1       A,1
2 B 2 Test2 B2       B,2
3 C 3 Test3 B3       C,3
4 D 4 Test4 B4       D,4
5 E 5 Test5 B5       E,5

如果vec &lt;- c(\"x\",\"y\", \"z\") 则输出如下:

newcol <- function(df, vec){
  df <- df %>% mutate(newcolumn = paste(get(\"x\"),get(\"y\"), get(\"z\"), sep = \",\"))
  return (df)
}

newcol(df, vec)

  x y     z  w newcolumn
1 A 1 Test1 B1 A,1,Test1
2 B 2 Test2 B2 B,2,Test2
3 C 3 Test3 B3 C,3,Test3
4 D 4 Test4 B4 D,4,Test4
5 E 5 Test5 B5 E,5,Test5

我想知道如何动态地完成这种连接。

  • 这个问题很快就会产生一些很好的答案!

标签: r dataframe dplyr


【解决方案1】:

使用粘贴!!!如图所示。

newcol <- function(df, vec){
  df %>% mutate(newcolumn = paste(!!!.[vec], sep = ","))
}

newcol(df, c("x", "y", "z"))
##   x y     z  w newcolumn
## 1 A 1 Test1 B1 A,1,Test1
## 2 B 2 Test2 B2 B,2,Test2
## 3 C 3 Test3 B3 C,3,Test3
## 4 D 4 Test4 B4 D,4,Test4
## 5 E 5 Test5 B5 E,5,Test5

这也有效,并且没有包依赖项。

newcol <- function(df, vec){
  cbind(df, newcolumn = apply(df[vec], 1, paste, collapse = ","))
}

如果逗号后跟空格可以,那么这有效:

newcol <- function(df, vec){
  cbind(df, newcolumn = apply(df[vec], 1, toString))
}

【讨论】:

  • 你知道我在哪里可以阅读更多关于这个.[vector] 符号的信息吗?熟悉.data[[col]] 但不是这个
  • 这是 magrittr 的一部分,因此请参阅该软件包的文档。点是指:管道的左侧。
  • 啊啊啊,是df的专栏精选,我明白了,谢谢!
【解决方案2】:

使用unite:

newcol <- function(df, vec){
  df <- df %>% unite("newcol", vec, sep = ",", remove = F)
  return (df)
}

vec <- c("x","z")
newcol(df,vec)

输出:

   newcol x y     z  w
1 A,Test1 A 1 Test1 B1
2 B,Test2 B 2 Test2 B2
3 C,Test3 C 3 Test3 B3
4 D,Test4 D 4 Test4 B4
5 E,Test5 E 5 Test5 B5

【讨论】:

    【解决方案3】:

    如果你想非常聪明,可以使用rlang 和 tidyselect 原则将参数作为名称而不是字符串传递:

    df <- data.frame(x = c("A","B","C","D","E"), y = c("1","2","3","4","5"),
                     z = c("Test1","Test2", "Test3","Test4","Test5"),
                     w =c("B1","B2","B3","B4","B5"))
    
    library(rlang)
    library(dplyr)
    
    newcol <- function(df, ...) {
      vec <- enquos(...)
      df <- df %>% mutate(newcolumn = paste(!!!vec, sep = ","))
      return(df)
    }
    
    df |> 
      newcol(x, y)
    
    #>   x y     z  w newcolumn
    #> 1 A 1 Test1 B1       A,1
    #> 2 B 2 Test2 B2       B,2
    #> 3 C 3 Test3 B3       C,3
    #> 4 D 4 Test4 B4       D,4
    #> 5 E 5 Test5 B5       E,5
    
    df |> 
      newcol(x, y, z)
    
    #>   x y     z  w newcolumn
    #> 1 A 1 Test1 B1 A,1,Test1
    #> 2 B 2 Test2 B2 B,2,Test2
    #> 3 C 3 Test3 B3 C,3,Test3
    #> 4 D 4 Test4 B4 D,4,Test4
    #> 5 E 5 Test5 B5 E,5,Test5
    

    【讨论】:

      猜你喜欢
      • 2016-12-09
      • 1970-01-01
      • 2014-07-30
      • 2013-04-23
      • 1970-01-01
      • 2022-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多