【问题标题】:loop through specific columns with criteria and break in r循环遍历具有条件的特定列并在 r 中中断
【发布时间】:2021-03-12 03:43:45
【问题描述】:

我想实现以下几点:

  1. 检查A001在哪一列,如果找到则返回列名,如果没有找到则返回0
  2. 有时有超过 CHECK 列.. 最多可以有 20 列和附加列.. 我如何指定循环以遍历这些列
  3. 不确定循环是否是正确的方法,但我觉得它是..我也愿意接受其他替代方法..

示例数据和我的试验如下

# 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])”导致错误..但我不知道要改成什么..请帮忙~

【问题讨论】:

  • 更改 pos = 1:5 name = rep("CHECK0", 5) pos = rep(0, 5) return(data.frame(pos, name)) 删除这一行 df = df % >% 变异(check_pos = pos, check_name = 名称)
  • 嗨@Stacker ..感谢您的回复,但这会导致2个问题.. >

标签: r loops criteria


【解决方案1】:

如果在 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

【讨论】:

  • 非常感谢@stacker,但如果我有后续问题怎么办?例如说相同的数据集,但有额外的检查列..我会在那里更新我的问题..因为我不确定是否要相应地改变..你能帮忙吗?谢谢~!!!
猜你喜欢
  • 2018-03-09
  • 2013-11-19
  • 1970-01-01
  • 2014-05-16
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 2018-12-19
相关资源
最近更新 更多