我有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列的庞大数据集上进行此操作。
答案 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
中定义的具有多个列组C2
,C3
,header_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