R 基于索引列创建新列

R 基于索引列创建新列,r,dataframe,dplyr,tidyverse,R,Dataframe,Dplyr,Tidyverse,我有一个包含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(

我有一个包含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]]
}

使用
数据的新解决方案。表

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(粘贴0(“col”,ID))
  • 将此值写入新列:
    col\u new:=

我们可以使用
行/列
基R
索引,这应该非常快

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

df1$colu\u new对于一种可能的
tidyverse
方法,使用
dplyr::mutate
purrr::map2\u int
结合使用如何。

库(dplyr)
图书馆(purrr)
变异(df,new_col=map2_int(row_number(),ID,~df[.x,.y]))
#>第1列第2列第3列ID新列
#> 1   12    0    4  1      12
#> 2    6    5    3  1       6
#> 3    5   21   42  2      21
数据


df另一种tidyverse方法,这次只使用
tidyr
dplyr

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

它比@markdly优雅的一行长,但是如果你像我一样,在大多数时候被
purr
搞糊涂了,这可能会更容易理解。

虽然我真的很喜欢dplyr和purrr,但我会接受这个答案,因为代码的意图更清楚。真的很好。我必须承认,我努力使用dplyr,但没有意识到map2_int。有
行数()
可以代替
1:n()
谢谢@akrun,这是一个很好的建议。我进行了编辑以包括
行编号()
——我认为这使代码更具可读性。