【发布时间】:2020-09-11 11:37:36
【问题描述】:
我经常需要将长而整齐的数据帧转换为宽格式。为此,我使用以下标准程序:
# Example data frame
df <- data.frame("ID" = rep(1:5, each = 4), "score" = runif(20, 0, 100), "location" = rep(c("a", "b", "c", "d"), 5))
# Transform into wide format
df_wide <- df %>%
group_by_at(vars(-score)) %>% # group by everything other than the value column.
mutate(row_id=1:n()) %>% ungroup() %>% # build group index
spread(key=location, value=score) %>% # spread
dplyr::select(-row_id)
我不想一遍又一遍地输入这个小脚本,而是想定义一个函数来自动完成。我发现了许多关于如何将列名包含为函数输入的有用帖子,但不知何故它不起作用或我收到错误消息。我做错了什么?
根据these 和this 的建议,以下是我的一些尝试(它们都不起作用):
wide_fun <- function(dat, key_name, value_name) {
group_by_at(vars(- !! sym(value_name))) %>% # group by everything other than the value column.
mutate(row_id=1:n()) %>% ungroup() %>% # build group index
spread(key=!! sym(key_name), value=!! sym(value_name)) %>% # spread
dplyr::select(-row_id)
}
wide_fun2 <- function(dat, key_name, value_name) {
key_col <- enquo(key_name)
value_col <- enquo(value_name)
group_by_at(vars(- !!value_col)) %>% # group by everything other than the value column.
mutate(row_id=1:n()) %>% ungroup() %>% # build group index
spread(key= !!key_col, value= !!value_col) %>% # spread
dplyr::select(-row_id)
}
wide_fun3 <- function(dat, key_name, value_name) {
group_by_at(vars(- value_name)) %>% # group by everything other than the value column.
mutate(row_id=1:n()) %>% ungroup() %>% # build group index
spread(key=key_name, value=value_name) %>% # spread
dplyr::select(-row_id)
}
wide_fun3(df, quote(location), quote(score))
感谢您的帮助!
【问题讨论】:
-
对于分组使用
group_by(across(all_of(value_name))),而不是分散使用pivot_wider(names_from=key_name, values_from=value_name)。 -
嗨!感谢您的建议,但我并不想改变我转换数据框的方式,我只是想知道为什么我不能像现在这样将列名包含到函数中。
-
另外
across()似乎是 dplyr 的新成员?我更新了它,但仍然收到找不到它的错误消息... -
该代码允许您使用字符向量作为输入。快速修改我原来的答案。
group_by(across(!all_of(value_name)))允许您为 value_name 指定一个或多个值,并将根据这些值以外的任何值进行分组。