我有以下数据框。
library(dplyr)
data_test = data.frame(va_te=c("yes", "", "no", "yes"),
va_ti=c("no", "", "yes", "no"),
va_ze=c("", "no", "yes", "no"),
jk_te=c(NA, 545, 876, 987),
jk_ti=c(876, 567, 908, 432),
jk_ze=c(987, 988, NA, 234),
loc=c(345, 898, 444, 321))
> data_test
va_te va_ti va_ze jk_te jk_ti jk_ze loc
1 yes no NA 876 987 345
2 no 545 567 988 898
3 no yes yes 876 908 NA 444
4 yes no no 987 432 234 321
我想使用两种模式来改变第 6 个变量(每组 3 个相似变量一个:va_ 和 jk_)。
对于第一组“va_”,我使用 across + start with + ifelse。
对于第二组“jk_”我想使用相同的方法,但因为我如果在测试中同时使用jk和va,我不知道如何编写这部分。
data_test_2 = data_test %>%
mutate(across(starts_with("va_"),
~ ifelse(.x == "", NA, .x), .names = "{col}")) %>%
mutate(jk_te = ifelse(va_te != "yes", NA,
ifelse(va_te == "yes" & is.na(jk_te), loc, jk_te))) %>%
mutate(jk_ti = ifelse(va_ti != "yes", NA,
ifelse(va_ti == "yes" & is.na(jk_ti), loc, jk_ti))) %>%
mutate(jk_ze = ifelse(va_ze != "yes", NA,
ifelse(va_ze == "yes" & is.na(jk_ze), loc, jk_ze)))
> data_test_2
va_te va_ti va_ze jk_te jk_ti jk_ze loc
1 yes no <NA> 345 NA NA 345
2 <NA> <NA> no NA NA NA 898
3 no yes yes NA 908 444 444
4 yes no no 987 NA NA 321
最简单的方法是首先将数据转换为长格式,其中一列表示
va_
列,一列表示 jk_
列,一列 suffix
分别表示 te, ti
或 ze
。
然后您可以轻松转换
va
和 jk
,特别是对于后者,您还可以使用相应的 va
列:
library(tidyr)
(data_lng <- data_test %>%
mutate(across(-loc, as.character)) %>% ## make character to put into same column
pivot_longer(-loc,
names_to = c("prefix", "suffix"),
names_sep ="_",) %>%
pivot_wider(names_from = prefix))
# # A tibble: 12 × 4
# loc suffix va jk
# <dbl> <chr> <chr> <chr>
# 1 345 te "yes" NA
# 2 345 ti "no" 876
# 3 345 ze "" 987
# 4 898 te "" 545
# 5 898 ti "" 567
# 6 898 ze "no" 988
# 7 444 te "no" 876
# 8 444 ti "yes" 908
# 9 444 ze "yes" NA
# 10 321 te "yes" 987
# 11 321 ti "no" 432
# 12 321 ze "no" 234
然后你可以像这样改变你的列:
(data_lng_mutated <- data_lng %>%
mutate(va = if_else(!nzchar(va), NA_character_, va),
jk = case_when(coalesce(va, "") != "yes" ~ NA_real_,
is.na(jk) ~ loc,
TRUE ~ as.numeric(jk))))
# # A tibble: 12 × 4
# loc suffix va jk
# <dbl> <chr> <chr> <dbl>
# 1 345 te yes 345
# 2 345 ti no NA
# 3 345 ze NA NA
# 4 898 te NA NA
# 5 898 ti NA NA
# 6 898 ze no NA
# 7 444 te no NA
# 8 444 ti yes 908
# 9 444 ze yes 444
# 10 321 te yes 987
# 11 321 ti no NA
# 12 321 ze no NA
最后一步是将其转换回宽格式:
data_lng_mutated %>%
pivot_wider(id_cols = loc, values_from = c("va", "jk"), names_from = suffix) %>%
relocate(loc, .after = last_col())
# # A tibble: 4 × 7
# va_te va_ti va_ze jk_te jk_ti jk_ze loc
# <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
# 1 yes no NA 345 NA NA 345
# 2 NA NA no NA NA NA 898
# 3 no yes yes NA 908 444 444
# 4 yes no no 987 NA NA 321