考虑以下数据集:
\ndf <- tibble(v1 = 1:5, v2= 101:105, v3 = c("v1", "v2", "v1", "v2", "v1"))\n\n# A tibble: 5 \xc3\x97 3\n v1 v2 v3 \n <int> <int> <chr>\n1 1 101 v1 \n2 2 102 v2 \n3 3 103 v1 \n4 4 104 v2 \n5 5 105 v1 \nRun Code Online (Sandbox Code Playgroud)\n我想生成一个新列,该列从 或 中获取值v1,v2具体取决于中列出的列v3。
# A tibble: 5 \xc3\x97 4\n v1 v2 v3 v4\n <int> <int> <chr> <dbl>\n1 1 101 v1 1\n2 2 102 v2 102\n3 3 103 v1 3\n4 4 104 v2 104\n5 5 105 v1 5\nRun Code Online (Sandbox Code Playgroud)\n通常,我会使用if_else,或者如果我有更多情况,则使用case_when。但是,我有很多列,所以我不想有case_when很多行长的语句。有没有办法让 R 将值解释为v3列名?我尝试过拥抱这个表达并{{ }}使用.data[[ ]]表达式,但我似乎无法找出正确的语法。
一个tidyverse选择是rowwise使用提取cur_data()
library(dplyr)\ndf %>% \n rowwise %>%\n mutate(v4 = cur_data()[[v3]]) %>% \n ungroup\n# A tibble: 5 \xc3\x97 4\n v1 v2 v3 v4\n <int> <int> <chr> <int>\n1 1 101 v1 1\n2 2 102 v2 102\n3 3 103 v1 3\n4 4 104 v2 104\n5 5 105 v1 5\nRun Code Online (Sandbox Code Playgroud)\n或者一个紧凑的方法是get或者在之后rowwise
df %>%\n rowwise %>%\n mutate(v4 = get(v3)) %>%\n ungroup\nRun Code Online (Sandbox Code Playgroud)\n或者在base R,使用行/列索引来加快执行速度
df$v4 <- as.data.frame(df[1:2])[cbind(seq_len(nrow(df)), \n match(df$v3, names(df)))]\ndf$v4\n[1] 1 102 3 104 5\nRun Code Online (Sandbox Code Playgroud)\n
这是一种矢量化方法,不需要逐行或map逐一进行。
df %>%
mutate(v4 = cbind(v1,v2)[ cbind(row_number(), match(v3, c("v1", "v2"))) ])
# # A tibble: 5 x 4
# v1 v2 v3 v4
# <int> <int> <chr> <int>
# 1 1 101 v1 1
# 2 2 102 v2 102
# 3 3 103 v1 3
# 4 4 104 v2 104
# 5 5 105 v1 5
Run Code Online (Sandbox Code Playgroud)
这是我们可以使用的一种方法pivot_longer:
pivot_longerfilterbind_cols() v1和v2library(tidyr)
library(dplyr)
df %>%
pivot_longer(
-v3,
names_to = "name",
values_to = "v4"
) %>%
filter(v3 == name) %>%
bind_cols(v1 = df$v1, v2=df$v2) %>%
select(v1, v2, v3, v4)
Run Code Online (Sandbox Code Playgroud)
v1 v2 v3 v4
<int> <int> <chr> <int>
1 1 101 v1 1
2 2 102 v2 102
3 3 103 v1 3
4 4 104 v2 104
5 5 105 v1 5
Run Code Online (Sandbox Code Playgroud)
diag您可以使用+ as.matrix(或t)尝试以下基本 R 代码
transform(
df,
v4 = diag(as.matrix(df[v3]))
)
Run Code Online (Sandbox Code Playgroud)
或者
transform(
df,
v4 = diag(t(df[v3]))
)
Run Code Online (Sandbox Code Playgroud)
这使
v1 v2 v3 v4
1 1 101 v1 1
2 2 102 v2 102
3 3 103 v1 3
4 4 104 v2 104
5 5 105 v1 5
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1578 次 |
| 最近记录: |