R语言mutate+case_when报错“Undefined columns selected”求助
问题描述
执行以下代码时出现错误:
test %>% mutate(Value = case_when(row_number() == 1 ~ val_1, row_number() == 2 ~ val_2))
错误信息:
Error in `mutate()`: ! Problem while computing `Value = case_when(row_number() == 1 ~ val_1, row_number() == 2 ~ val_2)`. Caused by error in `[.data.frame`: ! undefined columns selected
test数据框结构:
structure(list(ID = c("47ae3cc00d8515d4cbab4704bf7e6b79", "47ae3cc00d8515d4cbab4704bf7e6b79", "47ae3cc00d8515d4cbab4704bf7e6b79", "47ae3cc00d8515d4cbab4704bf7e6b79" ), Book = c("MyBookie.ag", "MyBookie.ag", "Pinnacle", "Pinnacle" ), Home = c("Kansas St Wildcats", "Kansas St Wildcats", "Kansas St Wildcats", "Kansas St Wildcats"), Away = c("Michigan St Spartans", "Michigan St Spartans", "Michigan St Spartans", "Michigan St Spartans"), Team = c("Kansas St Wildcats", "Michigan St Spartans", "Kansas St Wildcats", "Michigan St Spartans" ), Price = c(-110, -110, -114, 100), Points = c(1.5, -1.5, 1.5, -1.5), BEP = c(0.523809524, 0.523809524, 0.53271028, 0.5), Fair_Price = c(100, 100, -106.5420561, 106.5420561), Fair_BEP = c(0.5, 0.5, 0.515837104, 0.484162896), Hold = c(0.045454545, 0.045454545, 0.031674208, 0.031674208), Win = c(90.91, 90.91, 87.72, 100)), row.names = c(NA, -4L), spec = structure(list(cols = list(ID = structure(list(), class = c("collector_character", "collector")), Book = structure(list(), class = c("collector_character", "collector")), Home = structure(list(), class = c("collector_character", "collector")), Away = structure(list(), class = c("collector_character", "collector")), Team = structure(list(), class = c("collector_character", "collector")), Price = structure(list(), class = c("collector_double", "collector")), Points = structure(list(), class = c("collector_double", "collector")), BEP = structure(list(), class = c("collector_double", "collector")), Fair_Price = structure(list(), class = c("collector_double", "collector")), Fair_BEP = structure(list(), class = c("collector_double", "collector")), Hold = structure(list(), class = c("collector_double", "collector")), Win = structure(list(), class = c("collector_double", "collector"))), default = structure(list(), class = c("collector_guess", "collector")), delim = ","), class = "col_spec"), problems = <pointer: 0x00000153a4920d20>, class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"))
val_1和val_2的定义及结构:
# val_1定义与结构 val_1 <- (test[4,10] * test[2,11]) - (test[3,10] * 100) structure(list(Fair_BEP = -51.5617029958564), class = "data.frame", row.names = c(NA, -1L)) # val_2定义与结构 val_2 <- (test[3,10] * test[1,11]) - (test[4,10] * 100) structure(list(Fair_BEP = -48.3928424591436), class = "data.frame", row.names = c(NA, -1L))
问题核心:val_1和val_2是单行列的数据框,而case_when要求右侧必须是标量或长度匹配的向量,二维结构的data.frame无法直接参与赋值逻辑,导致报错。
解决方案
方法1:提取标量值重新定义val变量
修改val的定义,用[[或pull()提取单个数值(标量):
# 用[[直接提取标量 val_1 <- (test[[4,10]] * test[[2,11]]) - (test[[3,10]] * 100) val_2 <- (test[[3,10]] * test[[1,11]]) - (test[[4,10]] * 100) # 或用dplyr的pull函数,语义更清晰 val_1 <- (test %>% slice(4) %>% pull(Fair_BEP)) * (test %>% slice(2) %>% pull(Hold)) - (test %>% slice(3) %>% pull(Fair_BEP)) * 100 val_2 <- (test %>% slice(3) %>% pull(Fair_BEP)) * (test %>% slice(1) %>% pull(Hold)) - (test %>% slice(4) %>% pull(Fair_BEP)) * 100 # 执行原mutate代码即可正常运行 test %>% mutate(Value = case_when(row_number() == 1 ~ val_1, row_number() == 2 ~ val_2, TRUE ~ NA_real_))
方法2:在mutate内部直接计算,避免外部变量
利用dplyr的nth()函数,在当前数据框上下文直接提取指定行的数值,无需提前定义val变量:
test %>% mutate( Value = case_when( row_number() == 1 ~ (nth(Fair_BEP, 4) * nth(Hold, 2)) - (nth(Fair_BEP, 3) * 100), row_number() == 2 ~ (nth(Fair_BEP, 3) * nth(Hold, 1)) - (nth(Fair_BEP, 4) * 100), TRUE ~ NA_real_ # 为其余行设置NA,避免长度不匹配报错 ) )
方法3:直接构造赋值向量
因为仅需给前两行赋值,直接构造对应长度的向量完成赋值:
test %>% mutate(Value = c( (test[[4,10]] * test[[2,11]]) - (test[[3,10]] * 100), (test[[3,10]] * test[[1,11]]) - (test[[4,10]] * 100), NA_real_, NA_real_ ))
内容的提问来源于stack exchange,提问作者Aaron Morris
相关产品推荐
相关产品推荐

