left_join报错‘Join columns must be present’:position列未识别求助
问题:汇总中间位置频率数据时合并报错
我需要汇总处于中间position(即第一个和最后一个position之间)的f频率数据。处理思路是先筛选这类数据,执行summarise操作,再将新数据与原数据集重新合并。这个方法在训练数据上运行正常:
library(tidyverse) df %>% group_by(rowid) %>% # 筛选中间位置的数据并汇总频率 filter(position != first(position) & position != last(position)) %>% summarise(across(position), middle_position = mean(f, na.rm = TRUE), word = str_c(word, collapse=" ") ) %>% left_join(df, ., by = c("rowid", "position"))
但应用到实际数据时,出现以下错误:
Error in `left_join()`: ! Join columns must be present in data. ✖ Problem with `position`. Run `rlang::last_error()` to see where the error occurred. > rlang::last_error() <error/rlang_error> Error in `left_join()`: ! Join columns must be present in data. ✖ Problem with `position`. --- Backtrace: 1. ... %>% left_join(bnc_X, ., by = c("rowid", "position")) 3. dplyr:::left_join.data.frame(bnc_X, ., by = c("rowid", "position")) Run `rlang::last_trace()` to see the full context. > rlang::last_trace() <error/rlang_error> Error in `left_join()`: ! Join columns must be present in data. ✖ Problem with `position`. --- Backtrace: ▆ 1. ├─... %>% left_join(bnc_X, ., by = c("rowid", "position")) 2. ├─dplyr::left_join(bnc_X, ., by = c("rowid", "position")) 3. └─dplyr:::left_join.data.frame(bnc_X, ., by = c("rowid", "position")) 4. └─dplyr:::join_mutate(...) 5. └─dplyr:::join_cols(...) 6. └─dplyr:::standardise_join_by(...) 7. └─dplyr:::check_join_vars(by$x, x_names, error_call = error_call) 8. └─rlang::abort(bullets, call = error_call)
核心问题似乎是变量position未被识别,尝试多时仍无法解决,求帮助!
示例数据:
df <- data.frame( size = c(3,3,3, 3,3,3, 4,4,4,4, 5,5,5,5,5, 3,3,3), rowid = c(1,1,1,2,2,2,3,3,3,3,4,4,4,4,4,5,5,5), turn = c(rep("How are you?",3), rep("I'm fine.",3), rep("How's the weather?",4), rep("It's really very cold.",5), rep("I love you",3)), word = c("how","are","you", "i","'m","fine", "how","'s","the","weather", "it","'s","really", "very","cold", "i","love","you"), f = c(400,300,250, 600,555,1, 400,500,700,20, 390,500,177,200,35, 600,199,400), position = c(1,2,3, 1,2,3, 1,2,3,4, 1,2,3,4,5, 1,2,3) )
解决方案
报错根源是summarise里的across(position)写法错误:across()用于批量处理多列,单独写across(position)不会保留每个rowid下的所有position值,反而会导致汇总后的数据集丢失完整的position列,最终在left_join时无法匹配原表的对应列。
方法一:修正原代码逻辑
先标记中间位置,再分组计算均值,最后按rowid合并(无需按position匹配,因为中间位置的均值是整个组的属性):
library(tidyverse) # 生成汇总表:每个rowid对应中间位置的均值和拼接单词 summary_df <- df %>% group_by(rowid) %>% mutate(is_middle = position != first(position) & position != last(position)) %>% filter(is_middle) %>% summarise( middle_position = mean(f, na.rm = TRUE), middle_words = str_c(word, collapse = " ") ) # 合并到原表 df %>% left_join(summary_df, by = "rowid")
方法二:更高效的直接计算(推荐)
用group_by + mutate一步完成,无需额外合并操作:
df %>% group_by(rowid) %>% mutate( # 标记当前行是否为中间位置 is_middle = position != first(position) & position != last(position), # 计算当前组中间位置的f均值,无中间位置则返回NA middle_position = if_else(any(is_middle), mean(f[is_middle], na.rm = TRUE), NA_real_), # 拼接当前组中间位置的单词,无中间位置则返回NA middle_words = if_else(any(is_middle), str_c(word[is_middle], collapse = " "), NA_character_) ) %>% ungroup()
两种方法都能避免合并时的列缺失问题,第二种写法更简洁高效,还能保留原表所有行的完整信息。
内容的提问来源于stack exchange,提问作者Chris Ruehlemann
相关产品推荐
相关产品推荐

