假设我们有以下数据框:
df <- data.frame(seq(1, 21, 1),
seq(-60, 0, 3),
seq(200, 300, 5),
sample(1:3))
colnames(df) <- c("Var1", "Var2", "Var3", "Sample")
Var1 | Var2 | Var3 | 示例 |
---|---|---|---|
1 | -60 | 200 | 3 |
2 | -57 | 205 | 2 |
3 | -54 | 110 | 1 |
... | ... | ... | ... |
我想创建一个新变量,它的值是从与“示例”中的值对应的列中选择的。也就是说,对于上面的例子,结果应该类似于
Var1 | Var2 | Var3 | 示例 | Newvar |
---|---|---|---|---|
1 | -60 | 200 | 3 | 200 |
2 | -57 | 205 | 2 | -57 |
3 | -54 | 110 | 1 | 3 |
... | ... | ... | ... | ... |
我正在使用 dplyr,因此尝试了以下操作,但我不确定如何解决 paste0 未将“Sample”注册为对象的事实:
df %>%
mutate(Newvar = !!as.symbol(paste0("Var", Sample)))
任何帮助将不胜感激。
答案 0 :(得分:4)
您可以使用 c_across()
。
df %>%
rowwise() %>%
mutate(newvar = c_across(Var1:Var3)[Sample]) %>%
ungroup()
# # A tibble: 21 x 5
# Var1 Var2 Var3 Sample newvar
# <dbl> <dbl> <dbl> <int> <dbl>
# 1 1 -60 200 2 -60
# 2 2 -57 205 1 2
# 3 3 -54 210 3 210
# ...
答案 1 :(得分:0)
library(tidyverse)
df <- data.frame(seq(1, 21, 1),
seq(-60, 0, 3),
seq(200, 300, 5),
sample(1:3))
colnames(df) <- c("Var1", "Var2", "Var3", "Sample")
df %>%
mutate(Newbar = df$Sample %>%
map2_dbl(1:length(.), ~ df[..2, ..1]) )
#> Var1 Var2 Var3 Sample Newbar
#> 1 1 -60 200 3 200
#> 2 2 -57 205 1 2
#> 3 3 -54 210 2 -54
#> 4 4 -51 215 3 215
#> 5 5 -48 220 1 5
#> 6 6 -45 225 2 -45
#> 7 7 -42 230 3 230
#> 8 8 -39 235 1 8
#> 9 9 -36 240 2 -36
#> 10 10 -33 245 3 245
#> 11 11 -30 250 1 11
#> 12 12 -27 255 2 -27
#> 13 13 -24 260 3 260
#> 14 14 -21 265 1 14
#> 15 15 -18 270 2 -18
#> 16 16 -15 275 3 275
#> 17 17 -12 280 1 17
#> 18 18 -9 285 2 -9
#> 19 19 -6 290 3 290
#> 20 20 -3 295 1 20
#> 21 21 0 300 2 0
由 reprex package (v2.0.0) 于 2021 年 6 月 11 日创建
答案 2 :(得分:0)
这是一个基本的 R 解决方案。您使用第一个“[.]”将选择限制为前 3 行,然后在第二个“[.]”内使用两列矩阵“链接”选择:
df$Newvar <- df[1:3][cbind(1:nrow(df), df$Sample)]
#-------------
> df
Var1 Var2 Var3 Sample Newvar
1 1 -60 200 1 1
2 2 -57 205 2 -57
3 3 -54 210 3 210
4 4 -51 215 1 4
5 5 -48 220 2 -48
6 6 -45 225 3 225
7 7 -42 230 1 7
8 8 -39 235 2 -39
9 9 -36 240 3 240
10 10 -33 245 1 10
11 11 -30 250 2 -30
12 12 -27 255 3 255
13 13 -24 260 1 13
14 14 -21 265 2 -21
15 15 -18 270 3 270
16 16 -15 275 1 16
17 17 -12 280 2 -12
18 18 -9 285 3 285
19 19 -6 290 1 19
20 20 -3 295 2 -3
21 21 0 300 3 300
我得到的选择与 akrun 不同,因为没有调用 set.seed
并且您调用 sample
不够“丰富”。也许 dplyr 中有一个不同的 sample
函数具有不同的默认 replace
参数? (不,不是这样。只是用一个向量调用 sample
只会给你一个向量的排列,所以模式重复了 7 次。你会得到一个警告是采样的长度向量不是数据帧中行数的精确倍数。)
答案 3 :(得分:0)
使用 map2_dbl
中的 purrr
和列名作为引用而不是索引
library(dplyr)
library(purrr)
df$newvar <- map2_dbl(seq_len(nrow(df)), paste0("Var", df$Sample),
function(x, y) { df[x, y]})
df
#> Var1 Var2 Var3 Sample newvar
#> 1 1 -60 200 1 1
#> 2 2 -57 205 3 205
#> 3 3 -54 210 2 -54
#> 4 4 -51 215 1 4
#> 5 5 -48 220 3 220
#> 6 6 -45 225 2 -45
#> 7 7 -42 230 1 7
#> 8 8 -39 235 3 235
#> 9 9 -36 240 2 -36
#> 10 10 -33 245 1 10
#> 11 11 -30 250 3 250
#> 12 12 -27 255 2 -27
#> 13 13 -24 260 1 13
#> 14 14 -21 265 3 265
#> 15 15 -18 270 2 -18
#> 16 16 -15 275 1 16
#> 17 17 -12 280 3 280
#> 18 18 -9 285 2 -9
#> 19 19 -6 290 1 19
#> 20 20 -3 295 3 295
#> 21 21 0 300 2 0
由 reprex package (v2.0.0) 于 2021 年 6 月 12 日创建
答案 4 :(得分:0)
您可以将 get
与 rowwise()
一起使用
set.seed(1)
df <- data.frame(Var1 = sample(1:100, 5),
Var2 = sample(1:100, 5),
Var3 = sample(1:100, 5),
sample = sample(1:3, 5, T))
df
#> Var1 Var2 Var3 sample
#> 1 68 43 97 3
#> 2 39 14 85 1
#> 3 1 82 21 3
#> 4 34 59 54 1
#> 5 87 51 74 1
library(dplyr)
df %>% rowwise() %>%
mutate(newcol = get(paste0('Var', sample)))
#> # A tibble: 5 x 5
#> # Rowwise:
#> Var1 Var2 Var3 sample newcol
#> <int> <int> <int> <int> <int>
#> 1 68 43 97 3 97
#> 2 39 14 85 1 39
#> 3 1 82 21 3 21
#> 4 34 59 54 1 34
#> 5 87 51 74 1 87
由 reprex package (v2.0.0) 于 2021 年 6 月 12 日创建