【问题标题】:Create a new column based on an index column基于索引列创建新列
【发布时间】:2018-04-03 17:43:23
【问题描述】:

我有一个包含 n 个观察的数据集和一个包含观察索引的列,例如

col1 col2 col3 ID
12    0    4    1
6     5    3    1
5     21   42   2

并想根据我的索引创建一个新列

col1 col2 col3 ID col_new
12    0    4    1   12
6     5    3    1   6
5     21   42   2   21

没有 for 循环。其实我在做

col_new <- rep(NA, length(ID))
for (i in 1:length(ID))
{
   col_new[i] <- df[i, ID[i]]
}

有没有更好的或 (tidyverse) 方法?

【问题讨论】:

    标签: r dataframe dplyr tidyverse


    【解决方案1】:

    使用data.table的解决方案:

    library(data.table)
    # Using OPs data
    setDT(df)
    df[, col_new := get(paste0("col", ID)), 1:nrow(df)]
    
    # df
       col1 col2 col3 ID col_new
    1:   12    0    4  1      12
    2:    6    5    3  1       6
    3:    5   21   42  2      21
    

    解释:

    • 对于每一行:1:nrow(df)
    • 使用ID获取对应列:get(paste0("col", ID))
    • 将此值写入新列:col_new :=

    【讨论】:

      【解决方案2】:

      我们可以使用来自base Rrow/column 索引,这应该非常快

      df1$col_new <- df1[1:3][cbind(seq_len(nrow(df1)), df1$ID)]
      df1$col_new
      #[1] 12  6 21
      

      【讨论】:

      • 虽然我很喜欢 dplyr 和 purrr,但我会接受这个答案,因为代码的意图更加清晰。
      【解决方案3】:

      对于可能的tidyverse 方法,如何将dplyr::mutatepurrr::map2_int 结合使用。

      library(dplyr)
      library(purrr)
      
      mutate(df, new_col = map2_int(row_number(), ID, ~ df[.x, .y]))
      #>   col1 col2 col3 ID new_col
      #> 1   12    0    4  1      12
      #> 2    6    5    3  1       6
      #> 3    5   21   42  2      21
      

      数据

      df <- read.table(text = "col1 col2 col3 ID
      12    0    4    1
      6     5    3    1
      5     21   42   2", header = TRUE)
      

      【讨论】:

      • 真的很好。我不得不承认我在 dplyr 上很努力,但不知道 map2_int。
      • 您可以使用row_number() 代替1:n()
      • 谢谢@akrun,很好的建议。我已经编辑包含row_number() - 我认为它使代码更具可读性。
      【解决方案4】:

      另一种 tidyverse 方法,这次只使用 tidyrdplyr

      df %>%
          gather(column, col_new, -ID)  %>%  
          filter(paste0('col', ID) == column) %>%
          select(col_new) %>%
          cbind(df, .)
      

      它比@markdly 优雅的单线要长,但如果你像我一样,大部分时间都被purrr 弄糊涂了,这可能更容易阅读。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-11
        • 1970-01-01
        相关资源
        最近更新 更多