如何在R语言中根据指定列名从不同列取值生成新列?
解决R语言根据指定列名提取对应值的问题
嘿,我来帮你搞定这个需求!你想要在数据框df里新增一列val,让它根据每行day列给出的列名,从对应列中提取值对吧?你的思路方向没问题,但之前写的函数在索引处理上有偏差,我给你几个简单靠谱的解决方案:
先构造示例数据
首先咱们先把你给出的示例数据框准确构造出来,方便测试:
df <- data.frame( id = c(10,12,13,14,16,19,20,21,23), day = c("wed","wed","tue","thu","thu","fri","sun","mon","mon"), mon = c("a","b","h","j","y","e","y","u","i"), tue = c("y","e","y","u","i","y","e","y","u"), wed = c("b","h","j","b","h","j","y","a","b"), thu = c("j","y","b","h","j","y","a","b","h"), fri = c("j","b","h","j","y","a","b","h","j"), sat = c("b","h","j","b","h","j","y","a","b"), sun = c("a","b","h","j","y","e","y","u","i"), stringsAsFactors = FALSE # 避免字符自动转因子带来的问题 )
方案一:基础R原生方法(高效简洁)
用矩阵索引的方式可以快速实现需求,这是最原生的R写法,不需要额外包:
# 生成val列 df$val <- df[cbind(1:nrow(df), match(df$day, colnames(df)))]
原理解释:
match(df$day, colnames(df)):把每行的day值转换成它在数据框列名中对应的位置索引(比如"wed"对应的列索引是4)cbind(1:nrow(df), ...):把行索引(从1到数据框总行数)和上面得到的列索引组合成一个矩阵,R会用这个矩阵来精准提取每个位置的对应值
方案二:tidyverse/dplyr风格写法
如果你习惯用dplyr进行数据处理,也可以用行分组的方式实现:
library(dplyr) df <- df %>% rowwise() %>% # 让数据按行单独处理 mutate(val = pull(cur_data(), day)) %>% # 从当前行提取day指定列的值 ungroup() # 取消行分组,恢复常规数据框结构
验证结果
运行完上面任意一种方法后,你可以打印df查看结果,比如前几行的val列应该是:第一行b(对应wed列)、第二行h(对应wed列)、第三行y(对应tue列),完全符合你的预期。
关于你之前函数的问题
你之前写的lookupfunction里,which(x=x)这部分逻辑不对——x是整个df$day向量,这样没法拿到每行对应的行号,而且函数最后也没有返回对应列的取值,所以没法生成正确的val列。上面的两种方法都比自定义函数更高效简洁哦~
内容的提问来源于stack exchange,提问作者Andreas Hoff
相关产品推荐
相关产品推荐

