我正在清理R中的一些调查数据;根据对问题的回答分配变量1,0。说我有3个选项的问题; A,B,C;我有一个包含响应和逻辑变量的数据框:
df <- data.frame(a = rep(0,3), b = rep(0,3), c = rep(0,3), response = I(list(c(1),c(1,2),c(2,3))))
所以如果响应与列索引匹配(例如1 = a,2 = b,3 = c),我想将0改为1。
使用循环这很容易:
for (i in 1:nrow(df2)) df2[i,df2[i,"response"][[1]]] <- 1
使用apply / lapply / sapply / etc有没有办法做到这一点?类似的东西:
df <- sapply(df,function(x) x[x["response"][[1]]] <- 1)
或者我应该坚持使用循环?
答案 0 :(得分:2)
您可以使用?[
第三种形式的索引是通过带有一列的数字矩阵 对于每个维度:索引矩阵的每一行然后选择一个 数组的元素,结果是一个向量。负指数是 不允许在索引矩阵中。允许NA和零值:行 忽略包含零的索引矩阵,而忽略行 包含NA会在结果中产生NA。
# construct a matrix representing the index where the value should be one
idx <- with(df, cbind(rep(seq_along(response), lengths(response)), unlist(response)))
idx
# [,1] [,2]
#[1,] 1 1
#[2,] 2 1
#[3,] 2 2
#[4,] 3 2
#[5,] 3 3
# do the assignment
df[idx] <- 1
df
# a b c response
#1 1 0 0 1
#2 1 1 0 1, 2
#3 0 1 1 2, 3
答案 1 :(得分:0)
也许这有帮助
df[1:3] <- t(sapply(df$response, function(x) as.integer(names(df)[1:3] %in% names(df)[x])))
df
# a b c response
#1 1 0 0 1
#2 1 1 0 1, 2
#3 0 1 1 2, 3
或紧凑型选项
library(qdapTools)
df[1:3] <- mtabulate(df$response)
答案 2 :(得分:0)
或者你可以试试这个。
library(tidyr)
library(dplyr)
df1=df %>%mutate(Id=row_number()) %>%unnest(response)
df[,1:3]=table(df1$Id,df1$response)
a b c response
1 1 0 0 1
2 1 1 0 1, 2
3 0 1 1 2, 3