我想要处理的调查中有“检查所有适用项”。该 数据来自一个字符串变量,其中每个选择的响应者都是 编码到同一个变量中。受访者可以从21的列表中进行选择 选项,所有适用于他们的选项。我想创建一组21个假人 表示是/否的变量是否是受访者选择的特定 选项。
三个示例回复是:
id x
1 3, 13
2 1, 3, 8, 9, 11, 13
3 1, 9
...
我想要的是:
id x x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13
1 3, 13 0 0 1 0 0 0 0 0 0 0 0 0 1
2 1, 3, 8, 9, 11, 13 1 0 1 0 0 0 0 1 1 0 1 0 1
3 1, 9 1 0 0 0 0 0 0 0 1 0 0 0 0
...
在我尝试这样做的过程中,我读了一个id变量和响应变量
列入jp
列表,以便每个受访者在jp[[1]]
和他/她中都有一个id
jp[[2]]
中的回复:
> jp[[2]][1:3]
[1] "3, 13 "
[2] "1, 3, 8, 9, 11, 13 "
[3] "1, 9 "
然后我在逗号上通过strsplit
清理它们并将其放入jp[[4]]
:
> jp[[4]][1:3]
[[1]]
[1] "3" "13"
[[2]]
[1] "1" "3" "8" "9" "11" "13"
[[3]]
[1] "1" "9"
我在所有列表元素中找到了唯一值:
> taught <- as.character(sort(as.numeric(unique(unlist(jp[[4]])))))
> taught
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "256"
通过一些试验和错误,我发现我可以处理每一个 受访者的选择如下:
sapply(jp[[4]], function(x) any(x == "1"))
这似乎工作正常:
> table(sapply(jp[[4]], function(x) any(x == "1")))
FALSE TRUE
9404 1891
这是我期望的普遍性。
但是,因为每个受访者都可以有0-21个回复(子列表 我想我需要遍历每个中的每个独特响应 受访者的子列表,将结果写入新的列表元素。
我希望获取清单响应所在的列表元素jp[[4]]
并循环遍历'teach'的每个元素,看看是否存在于每个受访者中
子列表。
bla <- function(dt, lst) {
for (i in 1:length(lst)) {
subs <- list()
# apply function on each part, by row
subs[[i]] <- sapply(dt, function(x) any(x == taught[i]))
}
return(subs)
}
bla(jp[[4]], taught)
不幸的是,它似乎只适用于最后一个(21或'256')元素 在'teach'中,并没有保存到我在函数中定义的'subs'列表中。
> table(bla(jp[[4]], taught)[21])
FALSE TRUE
10645 650
> table(sapply(jp[[4]], function(x) any(x == "256")))
FALSE TRUE
10645 650
欢迎提出建议。感谢。
答案 0 :(得分:5)
,
作为数据集中的分隔符会产生问题。如果将其替换为其他字符,例如-
,则可以更轻松地使用它。假设你可以这样做,那么这应该可行。
tally<-function(df)
{
#create a data.frame with 23 columns, one for id, one for original x and 21 for responses
response_table=data.frame(matrix(nrow=1,ncol=23))
names(response_table)=c("id","x",paste("x",1:21,sep=""))
response_table$id=df$id
response_table$x=df$x
response_table[,3:23]=0
# Change the - to whatever separator you use
response_table[,as.numeric(unlist(str_split(df$x,'-')))+2]=1
return(response_table)
}
library(stringr)
test_data=data.frame(id=1:3,x=c("3-13","1-3-8-9-11-13","1-9"))
> test_data
id x
1 1 3-13
2 2 1-3-8-9-11-13
3 3 1-9
responses=ddply(test_data, .(id), tally)
> responses
id x x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21
1 1 3-13 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
2 2 1-3-8-9-11-13 1 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0 0 0 0 0 0
3 3 1-9 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
答案 1 :(得分:2)
示例数据
test_data=data.frame(id=1:3,x=c("3,13","1,3,8,9,11,13","1,9"),
stringsAsFactors=FALSE)
解
test_data_resp <- ddply(test_data,.(id),function(data,vc) {
v1 <- as.numeric(strsplit(data$x,split=",")[[1]])
vc[v1] <- 1
return(vc)},vc = numeric(23)
)