【问题标题】:Creating multiple new columns conditional on values of previous columns with modified names in R在 R 中以具有修改名称的先前列的值为条件创建多个新列
【发布时间】:2020-06-05 11:51:33
【问题描述】:

我有一个如下所示的数据框,但包含更多列和行。

dog_c  cat_c  cheese_c  hat_c 
3      4      3         2
3      1      2         5
5      2      1         4 

我想创建一个如下所示的数据框。我想从原始数据框中对给定列中的所有值进行平方,然后创建一个与原始数据框相同但末尾为 2 的列名。然后我想将它附加到原始数据框。

dog_c  cat_c  cheese_c  hat_c  dog_c2  cat_c2  cheese_c2  hat_c2 
3      4      3         2      9       16      9          4
3      1      2         5      9       1       2          5
5      2      1         4      25      4       1          16

我知道我可以通过以下方式为每个新列执行此操作。

df$dog_c2 <- (df$dog_c)^2

有没有人建议我如何更有效地做到这一点?

【问题讨论】:

    标签: r function dplyr tidyverse


    【解决方案1】:

    你也可以直接对数据框做同样的事情:

    df[paste0(names(df), 2)] <- df^2
    df
    
    #  dog_c cat_c cheese_c hat_c dog_c2 cat_c2 cheese_c2 hat_c2
    #1     3     4        3     2      9     16         9      4
    #2     3     1        2     5      9      1         4     25
    #3     5     2        1     4     25      4         1     16
    

    如果你想在dplyr做这个,你可以使用mutate_all

    library(dplyr)
    df %>% mutate_all(list(`2` = ~. ^2))
    

    如果我们只想对选定的列执行此操作,我们可以这样做:

    cols <- c('dog_c','cat_c') #Use regex if there are lot of columns.
    df[paste0(cols, 2)] <- df[cols]^2
    
    #  dog_c cat_c cheese_c hat_c dog_c2 cat_c2
    #1     3     4        3     2      9     16
    #2     3     1        2     5      9      1
    #3     5     2        1     4     25      4
    

    或者使用mutate_atdplyr

    df %>% mutate_at(cols, list(`2` = ~.^2))
    

    数据

    df <- structure(list(dog_c = c(3L, 3L, 5L), cat_c = c(4L, 1L, 2L), 
    cheese_c = 3:1, hat_c = c(2L, 5L, 4L)), class = "data.frame", 
    row.names = c(NA, -3L))
    

    【讨论】:

    • 如果我只想对原始数据框中的一部分列执行此操作怎么办?
    • @melbez 选择cols 变量中的列。执行df[paste0(cols, 2)] &lt;- df[cols]^2 并在dplyr 选项中使用muate_at
    【解决方案2】:

    我们可以在dplyr的开发版中使用mutateacross

    library(dplyr)
    df1 %>% 
        mutate(across(everything(), list(~ .x^2), names = "{col}2"))
    #  dog_c cat_c cheese_c hat_c dog_c2 cat_c2 cheese_c2 hat_c2
    #1     3     4        3     2      9     16         9      4
    #2     3     1        2     5      9      1         4     25
    #3     5     2        1     4     25      4         1     16
    

    或者对于选定的列

    nm1 <- c('dog_c','cat_c')
    df1 %>% 
        mutate(across(all_of(nm1), list(~ .x^2), names = "{col}2"))
    #   dog_c cat_c cheese_c hat_c dog_c2 cat_c2
    #1     3     4        3     2      9     16
    #2     3     1        2     5      9      1
    #3     5     2        1     4     25      4
    

    或者data.table

    library(data.table)
    setDT(df1)[, paste0(nm1, 2) := .SD^2, .SDcols = nm1]
    

    数据

    df1 <- structure(list(dog_c = c(3L, 3L, 5L), cat_c = c(4L, 1L, 2L), 
    cheese_c = 3:1, hat_c = c(2L, 5L, 4L)), class = "data.frame", 
    row.names = c(NA, -3L))
    

    【讨论】:

      猜你喜欢
      • 2014-11-25
      • 1970-01-01
      • 2023-01-10
      • 2016-11-25
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      • 2018-03-03
      • 2015-03-31
      相关资源
      最近更新 更多