在R中为数据框新增列:判断三列最大值对应类别
在R数据框中新增列获取最大值对应的类别
需要给数据框primary_game_fb新增一列primary_fb,取值为ff_num、si_num、fc_num三列中数值最大的列对应的类别(分别对应"FF"、"SI"、"FC")。
数据样例:
head(primary_game_fb, n = 20) pitcher game_date ff_num si_num fc_num <dbl> <date> <dbl> <dbl> <dbl> 1 405395 2022-05-15 0 0 0 2 424144 2022-04-07 1 8 0 3 424144 2022-04-08 1 2 0 4 424144 2022-04-13 0 2 0 5 424144 2022-04-17 0 10 0 6 424144 2022-04-19 0 4 0 7 424144 2022-04-22 0 11 0 8 424144 2022-04-24 1 6 0 9 425794 2022-04-07 6 28 15 10 425794 2022-04-14 8 22 20 11 425794 2022-04-19 3 25 27 12 425794 2022-04-24 7 28 20 13 425794 2022-04-29 10 26 21 14 425794 2022-05-04 8 28 24 15 425794 2022-05-15 6 31 17 16 425794 2022-05-20 10 25 19 17 425794 2022-05-26 14 25 27 18 425794 2022-05-31 25 30 21 19 425794 2022-06-05 11 30 25 20 425794 2022-06-11 6 37 34
尝试的方法及问题
方法1:使用case_when
代码:
primary_game_fb <- primary_game_fb %>% dplyr::mutate(primary_fb = case_when(ff_num > si_num & fc_num ~ "FF", si_num > ff_num & fc_num ~ "SI", fc_num > ff_num & si_num ~ "FC", TRUE ~ NA_real_))
报错信息:
Error in `dplyr::mutate()`: ! Problem while computing `primary_fb = case_when(...)`. Caused by error in `` names(message) <- `*vtmp*` ``: ! 'names' attribute [1] must be the same length as the vector [0]
错误原因:
- 逻辑表达式写法错误:
& fc_num实际是判断fc_num是否为非0值,而非ff_num > fc_num,正确逻辑应为ff_num > si_num & ff_num > fc_num。 - 类型不匹配:
NA_real_是数值型NA,但前面返回的是字符型字符串,需改用NA_character_。
方法2:使用嵌套ifelse
代码:
primary_game_fb <- primary_game_fb %>% dplyr::mutate(primary_fb = ifelse(ff_num > si_num & fc_num, "FF", ifelse(si_num > ff_num & fc_num, "SI", ifelse(fc_num > ff_num & si_num, "FC", NA))))
问题:无报错但结果不符合预期,比如第5行si_num=10远大于另外两列的0,但primary_fb返回NA。
原因:同样是逻辑条件错误,以si_num > ff_num & fc_num为例,& fc_num等价于& (fc_num != 0),第5行fc_num=0导致整个条件变为TRUE & FALSE,最终进入最后分支返回NA。
正确解决方案
方案1:修正逻辑条件的case_when
明确每个条件为当前列数值大于另外两列,同时统一NA类型并处理多列相等的情况:
primary_game_fb <- primary_game_fb %>% dplyr::mutate(primary_fb = case_when( ff_num > si_num & ff_num > fc_num ~ "FF", si_num > ff_num & si_num > fc_num ~ "SI", fc_num > ff_num & fc_num > si_num ~ "FC", # 处理两列最大值相等的情况,可自定义优先级 ff_num == si_num & ff_num > fc_num ~ "FF", si_num == fc_num & si_num > ff_num ~ "SI", ff_num == fc_num & fc_num > si_num ~ "FC", # 全0或三列相等时返回NA TRUE ~ NA_character_ ))
方案2:使用max.col函数(更简洁高效)
max.col可直接返回每行最大值所在的列索引,再通过索引匹配对应的类别:
primary_game_fb <- primary_game_fb %>% dplyr::mutate( # 获取最大值所在列的索引,ties.method处理多列相等的情况 max_col = max.col(select(., ff_num, si_num, fc_num), ties.method = "first"), # 匹配类别,全0时返回NA primary_fb = case_when( ff_num == 0 & si_num == 0 & fc_num == 0 ~ NA_character_, TRUE ~ c("FF", "SI", "FC")[max_col] ), # 可选:删除中间生成的max_col列 .keep = "unused" )
ties.method参数说明:"first":优先选择第一个出现的最大值列"last":优先选择最后一个出现的最大值列"random":随机选择一个最大值列
内容的提问来源于stack exchange,提问作者Drew_Haugen
相关产品推荐
相关产品推荐

