使用R中的第三个变量列表,在多个变量之间进行变异
我需要获得2016年有效值条件下的成绩列表(数学、语言、sci等)(使用R中的第三个变量列表,在多个变量之间进行变异,r,dplyr,mutate,R,Dplyr,Mutate,我需要获得2016年有效值条件下的成绩列表(数学、语言、sci等)(validity\u 2016==“yes”)的值,并输入一个名为grades{subjects}的新变量(如grades\u math) 结果应该是这样的: df<-tibble(person = c("Alice", "Bob", "Mary"), validity_2016 = c(NA, "yes", NA
validity\u 2016
==“yes”)的值,并输入一个名为grades{subjects}
的新变量(如grades\u math)
结果应该是这样的:
df<-tibble(person = c("Alice", "Bob", "Mary"),
validity_2016 = c(NA, "yes", NA),
likes_ham = c("no", "yes", "yes"),
grades_math_2015=c(6,2,4),
grades_math_2016=c(3,5,7),
grades_language_2015=c(7,1,9),
grades_language_2016=c(3,6,7),
grades_sci_2015=c(7,1,9),
grades_sci_2016=c(3,6,7),
grades_math=c(6,5,4),
grades_language=c(7,6,7),
grades_sci=c(7,6,9))
df我建议对每个受试者使用mutate
和ifelse
。比如:
df2=df%>%
变异(成绩数学=ifelse(validatiy数学=2016=“是”,成绩数学=2016,成绩数学=2015))
如果这种方法的缺点是你需要对每个主题重复它。这可以通过以下方式实现自动化:
out\u cols=c(“数学成绩”、“科学成绩”)
用于(列输入输出){
c15=0(颜色,“_2015”)
c16=0(col,“_2016”)
df=df%>%突变(!!sym(col):=ifelse(有效性_2016==“是”!!sym(c16),!!sym(c15)))
}
其中!!sym(x)
将保存在变量x
中的文本转换为变量名(例如,如果x=“sci”
则!!sym(x)
为我们提供变量sci
而不是文本“sci”
或变量x
)。tidyverse
和示例:
本例使用mutate
和case\u when
来分配所述变量。我将它包装在一个函数中,以防您经常这样做
library(tidyverse)
library(rlang)
make_grade_columns <- function(df, condition_col, year_view){
year_column_names <- colnames(df)[str_detect(colnames(df), year_view) & colnames(df) != condition_col & !str_detect(colnames(df), "validity")]
year_prior_column_names <- colnames(df)[str_detect(colnames(df), as.character(as.numeric(year_view) - 1)) & colnames(df) != condition_col]
return_col_names <- str_remove(year_column_names, "_\\d\\d\\d\\d")
df <- df %>% mutate(
!!return_col_names[1] := case_when(
(df %>% select(!!!condition_col)) == "yes" ~ !! sym(year_column_names[1]),
T ~ !! sym(year_prior_column_names[1])),
!!return_col_names[2] := case_when(
(df %>% select(!!!condition_col)) == "yes" ~ !! sym(year_column_names[2]),
T ~ !! sym(year_prior_column_names[2])),
!!return_col_names[3] := case_when(
(df %>% select(!!!condition_col)) == "yes" ~ !! sym(year_column_names[3]),
T ~ !! sym(year_prior_column_names[3])))
return(df)
}
make_grade_columns(df, "validity_2016", "2016") %>%
select(person, validity_2016, grades_math, grades_sci, grades_language)
# # A tibble: 3 x 5
# person validity_2016 grades_math grades_sci grades_language
# <chr> <chr> <dbl> <dbl> <dbl>
# 1 Alice NA 6 7 7
# 2 Bob yes 5 6 6
# 3 Mary NA 4 9 9
该函数将接受“是”回答并返回当年的值。如果答案为“否”,则它将返回前一年的值。您好,Andres,您是否可以减少列数?问题越简单,我们回答的速度就越快。事实上,我真正的问题是一个大约有109个变量的数据集,这对我来说不可能减少列数,因为我会失去IssueGod答案的背景。我认为它不像下面这样灵活,因为您必须为每个变量(col\u names[1:200]
)指定mutate中的参数,并将返回的col\u names括起来?是 啊如果您的用例需要,我可以使用for循环
使其更加灵活。让我知道模式和缩放用例,我可以更改代码。此外,如果您尝试使用前一年不可用的年份,此函数将对您发出警告。此外,在colnames中使用#s(如validity#u 2016)将对任何未命名validity的列(不包括grades
列)返回无意义的结果。
df<-tibble(person = c("Alice", "Bob", "Mary"),
validity_2016 = c(NA, "yes", NA),
likes_ham = c("no", "yes", "yes"),
grades_math_2015=c(6,2,4),
grades_math_2016=c(3,5,7),
grades_language_2015=c(7,1,9),
grades_language_2016=c(3,6,7),
grades_sci_2015=c(7,1,9),
grades_sci_2016=c(3,6,7),
grades_math=c(6,5,4),
grades_language=c(7,6,7),
grades_sci=c(7,6,9))
library(tidyverse)
library(rlang)
make_grade_columns <- function(df, condition_col, year_view){
year_column_names <- colnames(df)[str_detect(colnames(df), year_view) & colnames(df) != condition_col & !str_detect(colnames(df), "validity")]
year_prior_column_names <- colnames(df)[str_detect(colnames(df), as.character(as.numeric(year_view) - 1)) & colnames(df) != condition_col]
return_col_names <- str_remove(year_column_names, "_\\d\\d\\d\\d")
df <- df %>% mutate(
!!return_col_names[1] := case_when(
(df %>% select(!!!condition_col)) == "yes" ~ !! sym(year_column_names[1]),
T ~ !! sym(year_prior_column_names[1])),
!!return_col_names[2] := case_when(
(df %>% select(!!!condition_col)) == "yes" ~ !! sym(year_column_names[2]),
T ~ !! sym(year_prior_column_names[2])),
!!return_col_names[3] := case_when(
(df %>% select(!!!condition_col)) == "yes" ~ !! sym(year_column_names[3]),
T ~ !! sym(year_prior_column_names[3])))
return(df)
}
make_grade_columns(df, "validity_2016", "2016") %>%
select(person, validity_2016, grades_math, grades_sci, grades_language)
# # A tibble: 3 x 5
# person validity_2016 grades_math grades_sci grades_language
# <chr> <chr> <dbl> <dbl> <dbl>
# 1 Alice NA 6 7 7
# 2 Bob yes 5 6 6
# 3 Mary NA 4 9 9
make_grade_columns(df, "likes_ham", "2016")%>%
select(person, likes_ham, grades_math, grades_sci, grades_language)
# # A tibble: 3 x 5
# person likes_ham grades_math grades_sci grades_language
# <chr> <chr> <dbl> <dbl> <dbl>
# 1 Alice no 6 7 7
# 2 Bob yes 5 6 6
# 3 Mary yes 7 7 7