【问题标题】:Index based assignment with apply in R在 R 中应用基于索引的分配
【发布时间】:2017-07-18 01:13:40
【问题描述】:

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

还是我应该坚持循环?

【问题讨论】:

  • 你的预期输出是什么

标签: r loops apply


【解决方案1】:

您可以使用矩阵索引,来自?[

第三种索引形式是通过具有一列的数字矩阵 对于每个维度:索引矩阵的每一行然后选择一个 数组的元素,结果是一个向量。负指数是 不允许在索引矩阵中。 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

【讨论】:

    【解决方案2】:

    或者你可以试试这个。

    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
    

    【讨论】:

      【解决方案3】:

      也许这有帮助

      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)
      

      【讨论】:

        猜你喜欢
        • 2021-12-20
        • 2019-11-10
        • 1970-01-01
        • 1970-01-01
        • 2015-05-03
        • 1970-01-01
        • 2015-11-28
        • 1970-01-01
        • 2022-10-04
        相关资源
        最近更新 更多