使用条件循环遍历特定列并在 r 中中断
loop through specific columns with criteria and break in r
我想实现以下几点:
- 检查 A001 在哪一列,如果找到则 return 列名,但如果 none 找到则 return 0
- 有时有多个 CHECK 列.. 最多可能有 20 列并且还有其他列.. 我如何指定循环以循环遍历这些列
- 不确定循环是正确的方法,但我觉得它是..我也愿意接受其他选择..
示例数据和我的试验如下
# sample
mydf <- data.frame(case = c(1, 2, 3),
id = c(10, 11, 12),
CHECK1 = c("A001", "B001", "C001"),
CHECK2 = c("Z001", "K001", "C001"),
CHECK3 = c("Z001", "B001", "A001"))
for (i in 1:3) {
# giving out position and column name
mydf = mydf %>% mutate(CHECK_Pos = case_when(mydf[paste0("CHECK", i)] == "A001" ~ i * 1,
TRUE ~ 0),
CHECK_Name = case_when(mydf[paste0("CHECK", i)] == "A001" ~ paste0("CHECK", i),
TRUE ~ "CHECK0"))
}
这不起作用,因为它总是循环遍历所有列,直到所有行结束,但我不知道如何在匹配时停止循环。
我理想的输出是:
CHECK_Pos = c(1, 0, 3)
CHECK_Name = c("CHECK1", "CHECK0", "CHECK3")
请帮忙??非常感谢你~~!!
跟进问题:
如果我有更多列但我真的不知道如何更改代码怎么办
样本
mydf <- data.frame(case = c(1, 2, 3),
id = c(10, 11, 12),
CHECK1 = c("A001", "B001", "C001"),
CHECK2 = c("Z001", "B001", "C001"),
CHECK3 = c("Z001", "B001", "C001"),
CHECK4 = c("Z001", "B001", "A001"),
CHECK5 = c("Z001", "B001", "C001"))
改装试用:
get_colname = function(df, value) {
ind = which(sapply(mydf[3:7], function (x) {value %in% x}))
name = names(mydf[3:7])
name[-ind] = "CHECK0"
pos = 1:3
pos[-ind] = 0
if (length(ind) == 0) {
name = rep("CHECK0", 3)
pos = rep(0, 3)
}
df = df %>%
mutate(check_pos = pos,
check_name = name)
return(df)
}
get_colname(mydf, "A001")
然后我会收到错误:错误:列 check_name
的长度必须为 3(行数)或一,而不是 5
我知道可能是这个“name = names(mydf[3:7])”导致了错误..但我不知道要改成什么..请帮忙~
如果在 if
语句中使用 break
匹配,您可以停止,但我看不到将它放在代码中的什么位置。无论如何,这有效。简而言之,它检查每列的值是否为 %in%
。
get_colname=function(df, value) {
ind=which(sapply(mydf[3:5], function (x) {value %in% x}))
name=names(mydf[3:5])
name[-ind]="CHECK0"
pos=1:3
pos[-ind]=0
if (length(ind)==0) {
name=rep("CHECK0", 3)
pos=rep(0,3)
}
df=mutate(df, check_pos=pos, check_name=name)
return(df)
}
get_colname(mydf, "A001")
case id CHECK1 CHECK2 CHECK3 check_pos check_name
1 1 10 A001 Z001 Z001 1 CHECK1
2 2 11 B001 K001 B001 0 CHECK0
3 3 12 C001 C001 A001 3 CHECK3
get_colname(mydf, "D001")
case id CHECK1 CHECK2 CHECK3 check_pos check_name
1 1 10 A001 Z001 Z001 0 CHECK0
2 2 11 B001 K001 B001 0 CHECK0
3 3 12 C001 C001 A001 0 CHECK0
我想实现以下几点:
- 检查 A001 在哪一列,如果找到则 return 列名,但如果 none 找到则 return 0
- 有时有多个 CHECK 列.. 最多可能有 20 列并且还有其他列.. 我如何指定循环以循环遍历这些列
- 不确定循环是正确的方法,但我觉得它是..我也愿意接受其他选择..
示例数据和我的试验如下
# sample
mydf <- data.frame(case = c(1, 2, 3),
id = c(10, 11, 12),
CHECK1 = c("A001", "B001", "C001"),
CHECK2 = c("Z001", "K001", "C001"),
CHECK3 = c("Z001", "B001", "A001"))
for (i in 1:3) {
# giving out position and column name
mydf = mydf %>% mutate(CHECK_Pos = case_when(mydf[paste0("CHECK", i)] == "A001" ~ i * 1,
TRUE ~ 0),
CHECK_Name = case_when(mydf[paste0("CHECK", i)] == "A001" ~ paste0("CHECK", i),
TRUE ~ "CHECK0"))
}
这不起作用,因为它总是循环遍历所有列,直到所有行结束,但我不知道如何在匹配时停止循环。 我理想的输出是: CHECK_Pos = c(1, 0, 3) CHECK_Name = c("CHECK1", "CHECK0", "CHECK3") 请帮忙??非常感谢你~~!!
跟进问题: 如果我有更多列但我真的不知道如何更改代码怎么办
样本
mydf <- data.frame(case = c(1, 2, 3),
id = c(10, 11, 12),
CHECK1 = c("A001", "B001", "C001"),
CHECK2 = c("Z001", "B001", "C001"),
CHECK3 = c("Z001", "B001", "C001"),
CHECK4 = c("Z001", "B001", "A001"),
CHECK5 = c("Z001", "B001", "C001"))
改装试用:
get_colname = function(df, value) {
ind = which(sapply(mydf[3:7], function (x) {value %in% x}))
name = names(mydf[3:7])
name[-ind] = "CHECK0"
pos = 1:3
pos[-ind] = 0
if (length(ind) == 0) {
name = rep("CHECK0", 3)
pos = rep(0, 3)
}
df = df %>%
mutate(check_pos = pos,
check_name = name)
return(df)
}
get_colname(mydf, "A001")
然后我会收到错误:错误:列 check_name
的长度必须为 3(行数)或一,而不是 5
我知道可能是这个“name = names(mydf[3:7])”导致了错误..但我不知道要改成什么..请帮忙~
如果在 if
语句中使用 break
匹配,您可以停止,但我看不到将它放在代码中的什么位置。无论如何,这有效。简而言之,它检查每列的值是否为 %in%
。
get_colname=function(df, value) {
ind=which(sapply(mydf[3:5], function (x) {value %in% x}))
name=names(mydf[3:5])
name[-ind]="CHECK0"
pos=1:3
pos[-ind]=0
if (length(ind)==0) {
name=rep("CHECK0", 3)
pos=rep(0,3)
}
df=mutate(df, check_pos=pos, check_name=name)
return(df)
}
get_colname(mydf, "A001")
case id CHECK1 CHECK2 CHECK3 check_pos check_name
1 1 10 A001 Z001 Z001 1 CHECK1
2 2 11 B001 K001 B001 0 CHECK0
3 3 12 C001 C001 A001 3 CHECK3
get_colname(mydf, "D001")
case id CHECK1 CHECK2 CHECK3 check_pos check_name
1 1 10 A001 Z001 Z001 0 CHECK0
2 2 11 B001 K001 B001 0 CHECK0
3 3 12 C001 C001 A001 0 CHECK0