R语言循环多条件行比较报错,需生成指定列目标值
解决循环中的NA判断错误&实现目标值
我来帮你搞定这个问题!首先咱们先搞清楚你遇到的错误原因:
你的循环从i=1开始,当i=1的时候,i-1=0,而R里数据框的行索引是从1开始的,访问第0行只会返回NA。if语句需要明确的TRUE/FALSE值,遇到NA就会抛出你看到的missing value where TRUE/FALSE needed错误。另外,你初始化newcolumn为c(0)的方式也有问题——如果数据框行数大于1,这会导致长度不匹配的警告,应该直接用默认值来初始化。
修正后的循环方案
我们可以调整循环的起始位置,从第2行开始(因为第1行没有前一行可以对比),先把所有行的newcolumn设为默认的score*1,再单独处理符合条件的行:
# 先初始化newcolumn为默认值:score*1 mydata$newcolumn <- mydata$score * 1 # 从第2行开始循环,避免访问不存在的第0行 for (i in 2:nrow(mydata)){ if ((mydata$type_name[i] == "a") && (mydata$type_name[i-1] == "a") && (mydata$name[i] != mydata$name[i-1])){ mydata$newcolumn[i] <- mydata$score[i] * 3 } }
运行这段代码后,你会看到第二行的newcolumn正好是2*3=6,完全符合你的需求。
更简洁的非循环方案(推荐)
在R里处理这种行与行之间的对比,用dplyr包的lag()函数会更高效简洁,不用写循环:
library(dplyr) mydata <- mydata %>% mutate( newcolumn = if_else( # 用lag()获取前一行的type_name和name type_name == "a" & lag(type_name) == "a" & name != lag(name), score * 3, score * 1 ) )
lag()函数会自动帮你获取前一行的值,第一行的lag()结果是NA,if_else会把这种情况归到else分支,也就是使用score*1,完美适配你的逻辑。
内容的提问来源于stack exchange,提问作者user9220457
相关产品推荐
相关产品推荐

