r - 按标签属性合并data.frame列?
问题描述
假设您有一个 data.frame,其中某些列具有“标签”属性。
df1 <- data.frame(ID = letters[1:3], Qr1 = 1:3, Qr2 = 4:6, Qr3 = 7:9)
attr(df1$Qr1, 'label') <- 'dog'
attr(df1$Qr2, 'label') <- 'cat'
attr(df1$Qr3, 'label') <- 'bird'
您还有第二个类似的 data.frame,但具有不同的变量词干(“问题”而不是“Q”)。还有一个新变量,其“标签”属性为“鱼”,变量被重新排序(“猫”现在排在第三位,“鸟”现在排在第四位。)
df2 <- data.frame(ID = letters[4:6], Questionr1 = 10:12, Questionr2 = 13:15,
Questionr3 = 16:18, Questionr4 = 19:21)
attr(df2$Questionr1, 'label') <- 'dog'
attr(df2$Questionr2, 'label') <- 'fish'
attr(df2$Questionr3, 'label') <- 'cat'
attr(df2$Questionr4, 'label') <- 'bird'
您的目标是将“df1”与“df2”对齐,以便“df3”将它们的数据与“标签”属性合并,并遵循“df2”的变量命名(具有更多相关变量的变量命名):
> goal
ID Questionr1 Questionr2 Questionr3 Questionr4
1 a 1 NA 4 7
2 b 2 NA 5 8
3 c 3 NA 6 9
4 d 10 13 16 19
5 e 11 14 17 20
6 f 12 15 18 21
在将行与dplyr::bind_rows()
. 这适用于我的样本数据,有点,但不适用于我的实际数据(我认为是因为我的标签值很长)。
# rename columns by label for df1
temp1 <- df1
stem1 <- '^Qr'
idx1 <- grep(stem1, colnames(temp1))
nams1 <- colnames(temp1)[idx1]
for(i in seq_along(nams1)){
lab1 <- attr(temp1[[nams1[i]]], "label")
names(temp1) <- gsub(nams1[i], lab1, names(temp1))
}
# renames columns by label for df2
temp2 <- df2
stem2 <- "^Questionr"
idx2 <- grep(stem2, colnames(temp2))
nams2 <- colnames(temp2)[idx2]
for(i in seq_along(nams2)){
lab2 <- attr(temp2[[nams2[i]]], "label")
names(temp2) <- gsub(nams2[i], lab2, names(temp2))
}
# bind the temp dfs
temp21 <- dplyr::bind_rows(temp2, temp1)
names(temp21) <- colnames(df2)
> temp21
ID Questionr1 Questionr2 Questionr3 Questionr4
1 d 10 13 16 19
2 e 11 14 17 20
3 f 12 15 18 21
4 a 1 NA 4 7
5 b 2 NA 5 8
6 c 3 NA 6 9
是否有一个函数或更直接的方法,我可以使用它们的属性标签来合并这些 data.frame 列?理想情况下,我希望得到具有更多主干变量的 data.frame 的原始变量名称。
解决方案
这是一种(稍微不那么乏味)的方法,使用tidyverse
:
为“较大的”data.frame ( ) 中的属性 ( label
) 和问题 ( )定义一个查找表,并为查找和读取属性定义两个辅助函数。QR
df2
library(tidyverse)
get_label <- attr_getter("label")
lut <- tibble(Qr = df2 %>% select(-ID) %>% names) %>%
mutate(label = map_chr(Qr, ~ get_label(df2[[.]])))
lookup <- function(x) lut %>% filter(label == x) %>% pull(Qr)
用相应的标签重命名列,连接df1
和df2
重命名结果的列。
goal <- full_join(
df1 %>% rename_with(~ map_chr(.x, ~ get_label(df1[[.]])), .cols = -ID),
df2 %>% rename_with(~ map_chr(.x, ~ get_label(df2[[.]])), .cols = -ID)
) %>% rename_with(~ map_chr(.x, ~lookup(.)), .cols = -ID)
goal %>% select(sort(names(goal))) # optional reordering of columns
ID Questionr1 Questionr2 Questionr3 Questionr4
1 a 1 NA 4 7
2 b 2 NA 5 8
3 c 3 NA 6 9
4 d 10 13 16 19
5 e 11 14 17 20
6 f 12 15 18 21
推荐阅读
- r - 尝试根据列 R 中的字符串过滤数据框
- r - R str_extract 循环中的奇怪行为
- css - CSS :not 和 :first-child 用于同一类
- pandas - 将熊猫系列转换为数组
- javascript - 如何使用 Google Apps 脚本为每个活动创建(在特定的 if 语句中)添加唯一的 Google Meet 链接
- python - 使用 python 将 Excel 转换为 JSON 格式
- java - 通过在 main 方法中接受一个整数来打印一棵树
- javascript - 当我发布或接收消息时,Paho MQTT JS 客户端失去与 Mosquitto 代理的连接(错误 AMQJS0005E)
- python - 如何在 PDF 文件中查找表格网格线?
- r - 在 R 中查找和替换通配符