从 r 中的 data.frame 创建空 ("") 值的 table

Create a table of empty ("") values from a data.frame in r

我写了一些代码来创建一个 table 的列名和每个列中有多少个值的计数 NA。现在我想更改此代码以计算列中存在多少个空字符串 ""

这是一些通用数据:

d <- data.frame("ID" = c("A", "B", "", "C"),
                "VAL" = c(1, NA, 2, 3),
                "ORDER" = c(0, 3, 6, 7),
                "MARKET" = c("ENT", "HOUSE", "RETAIL", ""))

这是我的代码,它生成一个 table 列中有多少 NA
注意: 它只将包含至少 1 个 NA 的列放在 table 中,而这个 故意的。这是因为数据中有很多列,我希望 table 仅反映具有缺失值的列 - 我关心的列。

代码:

c_names <- names(d)
k <- 0
cont_NA <- NA
for (i in 1:(dim(d)[2])) {
  z <- unique(is.na(d[, i]))

  if(length(z) == 2){

    if(!is.na(cont_NA)){
      cont_NA <- c(cont_NA, c_names[i])
    }else{
      cont_NA <- c_names[i]
    }
  }
}
rm(i, k, z)

missing <- data.frame("Column" = NA,
                      "Missing_Values" = NA)
for(p in 1:length(cont_NA)){
  s <- sum(is.na(d[, c_names %in% cont_NA[p]]))

  missing[p, 1] <- cont_NA[p]
  missing[p, 2] <- s
}
rm(p, s, cont_NA)
missing

我的问题是如何将此代码转换为执行相同的操作,只是计数 ""?在上面的代码中,我使用了 is.na 函数,但我不知道有一个函数可以计算空字符串。

以上代码的示例输出是:

Column  Missing_Values
   VAL               1

我的问题的示例输出如下所示:

Column  Missing_Values
    ID               1
MARKET               1

不要使用 for 循环。查看 "apply" 函数。它会让你的生活变得更轻松。

# Sum up empty string per column over all columns using the apply function
tmp <- apply(d,2,function(x) sum(x=='',na.rm=TRUE)) 

# Create new dataframe of the results
res <- data.frame('Column'=names(tmp), 'Missing_Values'=as.numeric(tmp)) 

# Display results with nonzero values
res[res$Missing_Values!=0,] 

这是 dplyrtidyr 的解决方案。首先,我创建数据框。

d <- data.frame("ID" = c("A", "B", "", "C"),
                "VAL" = c(1, NA, 2, 3),
                "ORDER" = c(0, 3, 6, 7),
                "MARKET" = c("ENT", "HOUSE", "RETAIL", ""))

然后,我检查空字符串并对所有实例求和。我gather所有列从宽到长格式,并过滤掉那些空字符串为零的列。

d %>% 
  summarise_all(funs(sum(. == "", na.rm = TRUE))) %>% 
  gather(Column, Missing_Values) %>% 
  filter(Missing_Values > 0)

这给出了,

#   Column Missing_Values
# 1     ID              1
# 2 MARKET              1

怎么样

n <- colSums(d == "", na.rm = TRUE)
rev(stack(n[n > 0]))
#      ind values
# 1     ID      1
# 2 MARKET      1