r - 嵌套 if else 语句
问题描述
我有一个需要重新编码的大型数据集。数据集的每一行都是按时间顺序(时间)从单独的实验(id)中可能检测到的。然后手动验证每个可能的检测。当进行第一次真正检测时,它被标记(评论)“第一个”,当最后一次真正检测到时,它被标记为“最后一个”。如果没有检测到,则输入“无”。
我正在使用 if 语句进行重新编码。1)首先我想为变量 id 选择 first 和 last 都存在的所有情况,然后它需要用“no_comment”填写 first 和 last 之间的所有内容,然后它需要填写 first 和 last 之前或之后的所有内容与“MVND”。2) 选择仅存在“none”的 id 案例,并在该 id 案例的所有行中填充“none”。各个代码行都在工作,但由于某种原因,当我将它们组合到 ddply 中的 if 语句中时,它们并没有一起工作——它们只是返回原始的 data.frame。我认为我想要做的事情的 if else 结构是错误的。
#approximate data structure for this case:
y <-data.frame(id=c(rep("a",10),rep("b",10),rep("c",10)),time=rep(1:10, 3), Comments=rep(NA,30))
y$Comments[c(2,11,23)]<-"first"
y$Comments[c(9,19,30)]<-"last"
#x=y[y$id=="a",] #testing specific lines
#recursive process to step through the data
ddply(y,.(id), .fUN=function(x){
if(all(unique(na.omit(x$Comments))%in%c("first","last"))){
f<-which(x$Comments == "first")
l<-which(x$Comments == "last")
#Add no comment to all records between first and last
x$Comments[(f+1):(l - 1)]<- "no_comment"
#if 'first' isn't the first record add MVND to all things before 'first'
if(f>1){x$Comments[1:(f-1)]<-"MVND"}
#if 'last' isn't the last record add MVND to all records after 'last'.
if(l<nrow[x]){x$Comments[(l+1):nrow(x)]<-"MVND"}
}else if(unique(na.omit(x$Comments))=="none"){
x$Comments<-"none" #if the only unique comment is "none" set all comments to none
}
}
)
如果数据表是一种更好的方法来做到这一点,我想找出如何在 dt 中做到这一点。
#Edit:以上内容经过修改以扩展我正在处理的“第一个/最后一个”和“无”的两种情况。Jon spring 的解决方案非常适合我最初发布示例数据的方式,其中只有第一个/最后一个案例。
解决方案
不确定是否对您有用,但这是我在dplyr
. 由于这是矢量化的,我希望它比基于循环的方法运行得更快。
library(dplyr)
y %>%
group_by(id) %>%
dplyr::mutate(Comments2 = case_when( # in case `plyr` is loaded
cumsum(coalesce(lag(Comments == "last"), FALSE)) >= 1 ~ "MVND",
cumsum(coalesce(Comments == "first", FALSE)) < 1 ~ "MVND",
is.na(Comments) ~ "no_comment",
TRUE ~ Comments)) %>%
ungroup()
这里棘手的部分是 MVND 书挡,我计算我们是否通过了 alast
或尚未达到 a first
。coalesce
将第一项中的任何 NA 转换为第二项中的FALSE
值。cumsum
这里将TRUE
值相加。
这是我得到的结果,粘贴datapasta
为 tribble。据我所知,输出看起来符合预期:
tibble::tribble(
~id, ~time, ~Comments, ~Comments2,
"a", 1L, NA, "MVND",
"a", 2L, "first", "first",
"a", 3L, NA, "no_comment",
"a", 4L, NA, "no_comment",
"a", 5L, NA, "no_comment",
"a", 6L, NA, "no_comment",
"a", 7L, NA, "no_comment",
"a", 8L, NA, "no_comment",
"a", 9L, "last", "last",
"a", 10L, NA, "MVND",
"b", 1L, "first", "first",
"b", 2L, NA, "no_comment",
"b", 3L, NA, "no_comment",
"b", 4L, NA, "no_comment",
"b", 5L, NA, "no_comment",
"b", 6L, NA, "no_comment",
"b", 7L, NA, "no_comment",
"b", 8L, NA, "no_comment",
"b", 9L, "last", "last",
"b", 10L, NA, "MVND",
"c", 1L, NA, "MVND",
"c", 2L, NA, "MVND",
"c", 3L, "first", "first",
"c", 4L, NA, "no_comment",
"c", 5L, NA, "no_comment",
"c", 6L, NA, "no_comment",
"c", 7L, NA, "no_comment",
"c", 8L, NA, "no_comment",
"c", 9L, NA, "no_comment",
"c", 10L, "last", "last"
)
推荐阅读
- c++ - 如何实施一个良好的碰撞系统,同时也将具有成本效益?
- vhdl - 是否可以在测试台中定义循环函数
- ios - 如何在 Swift Flutter 插件中接收应用程序委托调用?
- javascript - Freecodecamp 上的“排队”练习
- vue.js - 从本地项目文件夹中打开 vue.js 中的 pdf 文件时出错
- runtime - 有没有解决运行时错误的有效方法?
- node.js - 从 Node.js 连接 MongoDB Atlas 的问题
- swift - 使用 swift 5 将字符串转换为 Int
- java - Spring Boot Jpa 删除除最后 50 条以外的所有记录
- flutter - 如何从 Flutter 中的另一个小部件更改 DropdownButton 值?