我正在尝试清理一些输入错误的数据.变量的问题允许五个选项中的多个响应,编号为1到5.数据已按以下方式输入(这只是一个示例 - 实际数据中有更多变量和更多观察值帧):
data
V1
1 1, 2, 3
2 1, 2, 4
3 2, 3, 4, 5
4 1, 3, 4
5 1, 3, 5
6 2, 3, 4, 5
Run Code Online (Sandbox Code Playgroud)
以下是重新创建示例数据的一些代码:
data = data.frame(V1 = c("1, 2, 3", "1, 2, 4", "2, 3, 4, 5",
"1, 3, 4", "1, 3, 5", "2, 3, 4, 5"))
Run Code Online (Sandbox Code Playgroud)
我真正需要的是要处理的数据更多...二进制 - 就像一组"是/否"问题 - 输入一个看起来更像的数据框:
data
V1.1 V1.2 V1.3 V1.4 V1.5
1 1 1 1 NA NA
2 1 1 NA 1 NA
3 NA 1 1 1 1
4 1 NA 1 1 NA
5 1 NA 1 NA 1
6 NA 1 1 1 1
Run Code Online (Sandbox Code Playgroud)
实际变量名称目前无关紧要 - 我可以轻松解决这个问题.此外,缺少的元素是"O","NA"还是空白并不重要 - 再次,这是我以后可以解决的问题.
我已经尝试过使用该软件包中的transform函数reshape以及使用不同的东西strsplit,但是我无法做到我正在寻找的东西.我还看了很多关于Stackoverflow的其他相关问题,但它们似乎并不是完全相同的问题.
你只需要编写一个函数并使用它apply.首先是一些虚拟数据:
##Make sure you're not using factors
dd = data.frame(V1 = c("1, 2, 3", "1, 2, 4", "2, 3, 4, 5",
"1, 3, 4", "1, 3, 5", "2, 3, 4, 5"),
stringsAsFactors=FALSE)
Run Code Online (Sandbox Code Playgroud)
接下来,创建一个接收行并根据需要进行转换的函数
make_row = function(i, ncol=5) {
##Could make the default NA if needed
m = numeric(ncol)
v = as.numeric(strsplit(i, ",")[[1]])
m[v] = 1
return(m)
}
Run Code Online (Sandbox Code Playgroud)
然后使用apply并转置结果
t(apply(dd, 1, make_row))
Run Code Online (Sandbox Code Playgroud)
很久以后,我终于开始创建一个以高效方式处理这类数据的包("splitstackshape").因此,为了方便他人(当然还有一些自我推销),这是一个紧凑的解决方案.
这个问题的相关功能是cSplit_e.
首先,默认设置保留原始列并NA用作填充:
library(splitstackshape)
cSplit_e(data, "V1")
# V1 V1_1 V1_2 V1_3 V1_4 V1_5
# 1 1, 2, 3 1 1 1 NA NA
# 2 1, 2, 4 1 1 NA 1 NA
# 3 2, 3, 4, 5 NA 1 1 1 1
# 4 1, 3, 4 1 NA 1 1 NA
# 5 1, 3, 5 1 NA 1 NA 1
# 6 2, 3, 4, 5 NA 1 1 1 1
Run Code Online (Sandbox Code Playgroud)
其次,删除原始列并0用作填充.
cSplit_e(data, "V1", drop = TRUE, fill = 0)
# V1_1 V1_2 V1_3 V1_4 V1_5
# 1 1 1 1 0 0
# 2 1 1 0 1 0
# 3 0 1 1 1 1
# 4 1 0 1 1 0
# 5 1 0 1 0 1
# 6 0 1 1 1 1
Run Code Online (Sandbox Code Playgroud)