【问题标题】:Loop to assign a value if an observation in one column is equal to other column's name in R如果一列中的观察值等于 R 中另一列的名称,则循环分配一个值
【发布时间】:2020-07-03 22:10:28
【问题描述】:

我有一个向量和一个数据集类似于:

id_vector <- as.character(c("n01", "n02", "n03"))
df_1 <- data.frame("id" = c("n01", "n02", "n02", "n03"), "n01" = NA, "n02" = NA,  "n03" = NA)
df_1$id <- as.character(df_1$id)

我希望数据集是:

df_2 <- data.frame("id" = c("n01", "n02", "n02", "n03"), "n01" = c(1, NA, NA, NA), "n02" = c(NA, 1, 1, NA),  "n03" = c(NA, NA, NA, 1))

解决方案应该很简单,例如:

for (i in id_vector){
  df_1[i][df_1$id == i] <- 1
}

但是,我不能使用两个 []。错误是:

Error in `[<-.data.frame`(`*tmp*`, df_1$id == i, value = 1) : 
duplicate subscripts for columns 

有什么帮助吗?

谢谢!

【问题讨论】:

    标签: r for-loop if-statement


    【解决方案1】:

    在这里,我们可以使用[[ 对向量进行子集化。 df_1[1] 仍然是具有单列的 data.frame

    for (i in id_vector){
       df_1[[i]][df_1$id == i] <- 1
      }
    
    identical(df_1, df_2)
    #[1] TRUE
    

    【讨论】:

      【解决方案2】:

      您可以创建一个行/列矩阵来将值更改为 1。

      df_1[id_vector][cbind(seq_len(nrow(df_1)), match(df_1$id, id_vector))] <- 1
      df_1
      
      #   id n01 n02 n03
      #1 n01   1  NA  NA
      #2 n02  NA   1  NA
      #3 n02  NA   1  NA
      #4 n03  NA  NA   1
      

      为了解释上面的内容,我们使用match 来获取要替换的列号,而seq_len(nrow(df_1)) 给我们一个序列1:nrow(df)。使用cbind 我们将它们转换为矩阵。

      cbind(seq_len(nrow(df_1)), match(df_1$id, id_vector))
      #     [,1] [,2]
      #[1,]    1    1
      #[2,]    2    2
      #[3,]    3    2
      #[4,]    4    3
      

      现在我们只对id_vector 列进行子集化,根据上述矩阵对数据框进行子集化并将值分配给1。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-11
        • 1970-01-01
        • 2021-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多