【问题标题】:Adding column name into a new column if it equals row value如果列名等于行值,则将列名添加到新列中
【发布时间】:2022-01-15 16:04:21
【问题描述】:

使用tidyverse,我想添加一个新列,其中包含一列的值,其中列名等于另一列的值。

我知道这个解释有点令人困惑,所以以一个简单的表格为例:

| Name | ID | A01 | A02 | A03 | A04 | A05 | new_column |
| ---- | -- | ----| --- | --- | --- | --- | ---------- |
| a    | A01| 2   | 3   | 1   | 4   | 6   | 2          |
| b    | A03| 3.4 | 4.5 | 2.2 | 3.6 | 7.2 | 2.2        |
| c    | A02| 1.3 | 2.0 | 4.4 | 6.5 | 9.2 | 2.0        |
| d    | A05| 0.8 | 7.6 | 3.3 | 4.5 | 1.1 | 1.1        |

当原始数据名称为d 时,使用类似于

的代码添加列“new_column”的任何想法
d %>% mutate(new_column = )

?

先谢谢了 :)

【问题讨论】:

  • 这个例子看起来像你想要 rowMin() 但也许只是 [
  • 请使用dput(d) 将您的数据粘贴到问题中以使其可重现,谢谢。

标签: r dataframe tidyverse


【解决方案1】:

您可以使用 R 中的 match 函数将 ID 的值与列名匹配。

df_new <- df %>%
  mutate(new_column = as.numeric(df[cbind(1:4, match(df$ID, names(df)))]))

这是df_new的输出:

  Name  ID A01 A02 A03 A04 A05 new_column
1    a A01 2.0 3.0 1.0 4.0 6.0        2.0
2    b A03 3.4 4.5 2.2 3.6 7.2        2.2
3    c A02 1.3 2.0 4.4 6.5 9.2        2.0
4    d A05 0.8 7.6 3.3 4.5 1.1        1.1

您可以查看this 帖子了解更多信息。

【讨论】:

    【解决方案2】:

    我们可以从purrr使用map2_dbl

    library(dplyr)
    library(purrr)
    df %>%
      mutate(new_column = map2_dbl(row_number(),ID,~df[.x,.y]))
    

    输出:

     Name  ID A01 A02 A03 A04 A05 new_column
    1    a A01 2.0 3.0 1.0 4.0 6.0        2.0
    2    b A03 3.4 4.5 2.2 3.6 7.2        2.2
    3    c A02 1.3 2.0 4.4 6.5 9.2        2.0
    4    d A05 0.8 7.6 3.3 4.5 1.1        1.1
    

    数据:

    df <- structure(list(Name = c("a", "b", "c", "d"), ID = c("A01", "A03", 
    "A02", "A05"), A01 = c(2, 3.4, 1.3, 0.8), A02 = c(3, 4.5, 2, 
    7.6), A03 = c(1, 2.2, 4.4, 3.3), A04 = c(4, 3.6, 6.5, 4.5), A05 = c(6, 
    7.2, 9.2, 1.1)), class = "data.frame", row.names = c(NA, -4L))
    

    【讨论】:

      【解决方案3】:

      我们可能会使用cur_data()

      library(dplyr)
      df %>% 
         rowwise %>% 
         mutate(new_column = cur_data()[[cur_data()$ID]]) %>%
         ungroup
      # A tibble: 4 × 8
        Name  ID      A01   A02   A03   A04   A05 new_column
        <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>      <dbl>
      1 a     A01     2     3     1     4     6          2  
      2 b     A03     3.4   4.5   2.2   3.6   7.2        2.2
      3 c     A02     1.3   2     4.4   6.5   9.2        2  
      4 d     A05     0.8   7.6   3.3   4.5   1.1        1.1
      

      【讨论】:

      • 我用 cur_column 试了一整天!
      【解决方案4】:
      library(tidyverse)
      
      df %>% 
        pivot_longer(-c(Name, ID)) %>% 
        transmute(Name, ID, new_column = ifelse(ID == name, value, NA_real_)) %>% 
        drop_na(new_column) %>% 
        left_join(df)
      

      【讨论】:

        【解决方案5】:

        这个语法有点奇怪,但确实有效。

        d$new_column <- d[unique(d$ID)][cbind(1:nrow(d), match(d$i, unique(d$ID)))]
        

        这类似于 Vishal 的回答,但它确保了 new_column 的变量类型是正确的(他们的回答可能会给你字符值而不是 new_column 中的数值)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-18
          • 2022-07-06
          • 1970-01-01
          相关资源
          最近更新 更多