基于索引的分配,适用于R

时间:2017-07-18 01:13:41

标签: r loops apply

我正在清理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)

或者我应该坚持使用循环?

3 个答案:

答案 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