在 R 中分离不整洁的数据 - ODK 清理

Separating untidy data in R - ODK cleanup

为了整理数据集的一部分,我需要将一列分成几列。这些数据采用类似于以下的形式:

set.seed(2133)
df <- data.frame(a = paste(sample(1:9, 5, replace=T), sample(c("", "%2", "%3"), 5, replace=T),  sample(c("", "%3", "%4"), 5, replace=T), sep="")) 
df
      a
1     6
2 2%3%4
3   6%2
4   3%2
5 5%2%4

Tidyr 的单独函数无法完成这项工作,我的最佳想法是一系列 ifelse 语句,如下所示:

df$One <- ifelse(grepl("1", df$a) == T, 1, 0)
df$Two <- ifelse(grepl("2", df$a) == T, 1, 0)
          a One Two
1     6   0   0
2 2%3%4   0   1
3   6%2   0   1
4   3%2   0   1
5 5%2%4   0   1

进行此类整理的最佳方法是什么。我相信很多使用开放数据工具包 (ODK) 进行数据收集的人都会遇到这个问题。

我们可以用 sapply 循环模式(即 1、2),得到一个逻辑矩阵,通过用 + 包装强制转换为二进制并将其分配为 [=32= 中的新列]

df[c("One", "Two")] <- +(sapply(1:2, grepl, df$a))
df
#     a One Two
#1     6   0   0
#2 2%3%4   0   1
#3   6%2   0   1
#4   3%2   0   1
#5 5%2%4   0   1

如果这是为了获取 'a' 列中每个唯一值的二进制输出,我们可以通过分隔符 (%) 拆分 'a' 中的字符串,输出 list 可以转换为 data.frame 使用 stacktransform 将 'values' 列转换为 factor class 通过指定 levels 并执行 table

table(transform(stack(setNames(strsplit(as.character(df$a), "[%]"),
       1:nrow(df))), values = factor(values, levels= 1:6))[2:1])

或者我们可以在拆分后使用 qdapTools 中的一个方便的函数 mtabulate

library(qdapTools)
mtabulate(strsplit(as.character(df$a), "[%]"))