【问题标题】:Changing values in dataframe iteraring over all rows and multiple columns更改数据框中的值迭代所有行和多列
【发布时间】:2019-01-18 14:11:49
【问题描述】:

我需要更改我的数据框中迭代行的一些值。对于每一行,如果某列中有 1,我需要将其他列中的 0 值更改为 NA。

我有一个可以运行的代码,但是在使用更大的数据集时速度非常慢。

data = data.frame(id=c("A","B","C"),V1=c(1,0,0),V2=c(0,0,0),V3=c(1,0,1))
cols = names(data)[2:4]

for (i in 1:nrow(data)){
  if(any(data[i,cols]==1)){
    data[i,cols][data[i,cols]==0]=NA
  }
}

我有一个示例数据集

data
  id V1 V2 V3
1  A  1  0  1
2  B  0  0  0
3  C  0  0  1

预期的(和实际的)结果是

data
  id V1 V2 V3
1  A  1 NA  1
2  B  0  0  0
3  C NA NA  1

我怎样才能以更优化的方式编写这个?

【问题讨论】:

  • 试试i1 <- rowSums(data[-1] == 1) > 0;data[-1][i1,] <- NA^ !data[-1][i1,]

标签: r dataframe


【解决方案1】:

单线可以,

data[rowSums(data[-1]) > 0,] <- replace(data[rowSums(data[-1]) > 0,], 
                                        data[rowSums(data[-1]) > 0,] == 0, 
                                        NA)
data
#  id V1 V2 V3
#1  A  1 NA  1
#2  B  0  0  0
#3  C NA NA  1

为了避免反复计算同一个表达式,我们可以先定义它,即

v1 <- rowSums(data[-1]) > 0
data[v1,] <- replace(data[v1,], 
                     data[v1,] == 0, 
                     NA)

【讨论】:

    【解决方案2】:

    假设您想根据V3 中的值更改V1V2 列的值,使用dplyr 很容易。我们可以在mutate_atfuns 参数中指定要更改其值的列,并指定要更改值的条件。

    library(dplyr)
    
    data %>% mutate_at(vars(V1:V2), funs(replace(., V3 == 1 & . == 0, NA)))
    
    #  id V1 V2 V3
    #1  A  1 NA  1
    #2  B  0  0  0
    #3  C NA NA  1
    

    【讨论】:

      【解决方案3】:

      我们可以在base R 中执行此操作,方法是使用rowSums 创建一个逻辑向量,然后根据此索引更新数字列

      i1 <- rowSums(data[-1] == 1) > 0
      data[-1][i1,] <- NA^ !data[-1][i1,]
      data
      #  id V1 V2 V3
      #1  A  1 NA  1
      #2  B  0  0  0
      #3  C NA NA  1
      

      如果索引需要基于单个列,例如“V3”,请将“i1”更改为

      i1 <- data$V3 == 1
      

      并在使用 'i1' 对行进行子集化后更新其他数字列,创建一个带否定的逻辑矩阵(! - 对于 0 值返回 TRUE,所有其他值返回 FALSE)。然后,在逻辑矩阵上使用NA^ 返回 NA 为 TRUE 和 1 为其他值。由于只有二进制值,因此可以更新

      data[i1, 2:3] <- NA^!data[i1, 2:3]
      

      【讨论】:

      • NA^是什么意思?
      • @user570271 将 TRUE 值替换为 NA 是一种更简单的方法,即..v1 &lt;- c(TRUE, FALSE, FALSE); NA^v1。在示例“数据”中,我们使用!data[i1, 2:3] 创建一个逻辑矩阵,其中 TRUE 值为 0,其他所有值为 FALSE。 NA^ 将 TRUE 返回 NA,其他返回 1
      猜你喜欢
      • 2017-01-16
      • 1970-01-01
      • 2018-08-21
      • 1970-01-01
      • 2023-01-14
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多