在列中搜索值,并在新列中返回“ true”或“ false”

时间:2018-07-31 13:13:12

标签: r

我有header_class这条数据,其中包含有关该字段的类的信息:

> header_class <- data.frame(header = c("name","type","format"),
+                            field = c("C1","C1","C2"))
> header_class
  header field
1   name    C1
2   type    C1
3 format    C2

我还有另一个data,标题的行是列。

> data <- data.frame(name = c("","Name2","Name3"),
+                    type = c(NA,"","Type3"),
+                    format = c("A",NA,"C"))
> data
   name  type format
1        <NA>      A
2 Name2         <NA>
3 Name3 Type3      C

我需要一个函数来验证某些条件,例如:

如果存在at least one field filled,则应在TRUE中返回一个new column值,如下所示:

> result
   name  type format   C1    C2
1        <NA>      A FALSE TRUE
2 Name2         <NA> TRUE  FALSE
3 Name3 Type3      C TRUE  TRUE

我已经尝试过使用它,但是不能使用它,因为例如它也具有""" "值。

> result <- cbind(data, sapply(split(as.character(header_class$header), as.character(header_class$field)),
+                                     function(x) rowSums(!is.na(data[x])) >0))
> result
   name  type format   C1    C2
1        <NA>      A TRUE  TRUE
2 Name2         <NA> TRUE FALSE
3 Name3 Type3      C TRUE  TRUE

我还尝试添加|条件来检查是否rowSums(data[x]!=""),但仍然不这样做,并返回了TRUE

我在做什么错?如果还有其他建议,我也将不胜感激。 我还需要在具有超过400列的庞大数据集上进行此操作。

2 个答案:

答案 0 :(得分:1)

在执行算法之前,在此处对您的数据运行此操作:

这将用NA替换所有空单元格"", " ", " .. ",依此类推。

data[] <- lapply(data,sub,pattern="^\\s*$",replacement=NA)

答案 1 :(得分:1)

我仍然不确定我是否了解这个问题,或者不确定header_class是如何发挥作用的。

以下内容再现了您的预期输出

transform(data,
    C1 = (!is.na(name) & name != "") | (!is.na(type) & type != ""),
    C2 = !is.na(format) & format != "")
#   name  type format    C1    C2
#1        <NA>      A FALSE  TRUE
#2 Name2         <NA>  TRUE FALSE
#3 Name3 Type3      C  TRUE  TRUE

更新

对于在C1中定义的具有多个列组C2C3header_class,...的更一般的情况,您可以执行以下操作

library(tidyverse)
data %>%
    rowid_to_column("row") %>%
    gather(k, v, -row) %>%
    left_join(header_class, by = c("k" = "header")) %>%
    group_by(row, field) %>%
    mutate(flag = sum(is.na(v)) + sum(v == "", na.rm = T) < n()) %>%
    spread(k, v) %>%
    spread(field, flag) %>%
    summarise_all(funs(first(.[!is.na(.)])))
## A tibble: 3 x 6
#    row format name  type  C1    C2
#  <int> <chr>  <chr> <chr> <lgl> <lgl>
#1     1 A      ""    NA    FALSE TRUE
#2     2 NA     Name2 ""    TRUE  FALSE
#3     3 C      Name3 Type3 TRUE  TRUE