r - 如何使用 R 中的后缀组合变量对?
问题描述
我有一个非常宽的数据集(1,000 多列),其中大约 160 个是以下格式的对:Var1.r 和 Var1.s;Var2.r 和 Var2.s 等等。
这是现在数据的一个小例子:
df <- tibble(Var1.r=c("Apple", "Pear", NA), Var1.s = c(NA, NA, "Dog"),
Var2.r = c("Boat", NA, NA), Var2.s = c(NA, "Platypus", NA),
AnotherVar = c(1,2,3))
# A tibble: 3 x 5
Var1.r Var1.s Var2.r Var2.s AnotherVar
<chr> <chr> <chr> <chr> <dbl>
1 Apple NA Boat NA 1
2 Pear NA NA Platypus 2
3 NA Dog NA NA 3
我希望它看起来像什么:
> df2
# A tibble: 3 x 3
Var1 Var2 AnotherVar
<chr> <chr> <dbl>
1 Apple Boat 1
2 Pear Platypus 2
3 Dog NA 3
我编写了一个函数来合并每对列merge_columns
,它将两列作为参数并返回所需的合并列。通常我会做类似的事情:
df2 <- df %>%
mutate(Var1 = merge_cols(Var1.r, Var1.s),
Var2 = merge_cols(Var2.r, Var2.s))
然后删除所有 .r 和 .s 列。除了我不想写同一行 80 次。
应该有更好的方法吧?
更新:我最终选择了一个丑陋但可行的解决方案。
# select all the ".s" columns
# (which will always have their .r counterparts)
to_merge <- df %>% select(ends_with(".s")) %>% names()
S <- NA
# loop through all the .s column names
for (S in to_merge) {
R <- gsub('(.+).s', '\\1.r', S) #create the equivalent .r col name
# merge them using merge_cols() and save them to the .r column
df[R] <- merge_cols(df[[S]],df[[R]])
}
# drop all the .s columns
df <- df %>% select(-ends_with(".s"))
# rename the variables that end in .r to be the "main" variable
names(df) <- gsub('(.+).r$', '\\1', names(df))
它超级难看,但它比重塑数据框更快(因为我有太多列但没有那么多行),并且允许我根据我想要合并数据的方式使用自定义 merge_cols 函数。
解决方案
您应该能够通过将数据框转换为长格式,然后解析列名,然后删除缺失值来做到这一点。例如:
library(dplyr)
library(tidyr)
df <-
tibble(
Var1.r = c("Apple", "Pear", NA),
Var1.s = c(NA, NA, "Dog"),
Var2.r = c("Boat", NA, NA),
Var2.s = c(NA, "Platypus", NA),
AnotherVar = c(1, 2, 3)
)
df %>% gather(Var, Val, -AnotherVar) %>%
separate(Var, into=c("Name", "Suffix"), sep="\\.") %>%
drop_na(Val) %>%
select(-Suffix) %>%
spread(Name, Val)
# A tibble: 3 x 3
AnotherVar Var1 Var2
<dbl> <chr> <chr>
1 1 Apple Boat
2 2 Pear Platypus
3 3 Dog NA
或者更笼统地说,假设它们都以以下开头,则捕获您想要gather
的starts_with
变量Var
:
df <-
tibble(
Var1.r = c("Apple", "Pear", NA),
Var1.s = c(NA, NA, "Dog"),
Var2.r = c("Boat", NA, NA),
Var2.s = c(NA, "Platypus", NA),
AnotherVar = c(1, 2, 3),
AnotherVar2 = c("a", NA, "c"),
AnotherVar3 = c("a1", "b2", NA)
)
df %>% gather(Var, Val, starts_with("Var")) %>%
separate(Var, into=c("Name", "Suffix"), sep="\\.") %>%
drop_na(Val) %>%
select(-Suffix) %>%
spread(Name, Val)
# A tibble: 3 x 5
AnotherVar AnotherVar2 AnotherVar3 Var1 Var2
<dbl> <chr> <chr> <chr> <chr>
1 1 a a1 Apple Boat
2 2 NA b2 Pear Platypus
3 3 c NA Dog NA
推荐阅读
- c++ - 这是否意味着内存泄漏?
- javascript - 需要删除句子中间的特殊字符,而不是字符串的开头和结尾
- php - 从当月选择记录而不进行全表扫描
- sql - 隐藏左连接列上除第一行以外的所有数据
- pandas - 如何在熊猫数据框中正确使用关键字“列”?
- java - 当主题中没有更多记录时如何在Kafka Consumer中刷新数据批处理
- javascript - 在 Angular 中禁用单击和键盘功能
- c# - 通过 Microsoft 团队机器人访问团队用户个人资料图像
- linux - 为什么我的 shellcode 在推送指令上崩溃?
- neo4j - 使用“apoc.load.json”将 json 加载到 Neo4j 中:数据检索不完整