有条件地替换数据框中的字符串

时间:2019-06-12 03:04:02

标签: r

DF <- data.frame("ID" = c(901, 902, 903, 904, 909), "INT" = c(0, 1, 0, 1, 1))

> DF
   ID INT
1 901   0
2 902   1
3 903   0
4 904   1
5 909   1

我想在INT = 1时替换ID列中的“ 9”,因此,它应如下所示:

 New_DF
   ID INT
1 901   0
2 802   1
3 903   0
4 804   1
5 809   1

我已经尝试过

if(DF$INT == "1") {
  gsub("^9", "8", DF$ID) 
}

它给我以下错误:

  

警告信息:       在if(DF $ INT ==“ 1”){:         条件的长度> 1,并且只会使用第一个元素

5 个答案:

答案 0 :(得分:2)

如果logINT,则可以使用1查找数字位数,然后减去10升至数字位数。这样,ID仍将是numeric

digits = floor(log(DF$ID, 10))
transform(DF, ID = ID - (10^digits) * (floor(ID/(10^digits)) == 9) * (INT))
#   ID INT
#1 901   0
#2 802   1
#3 903   0
#4 804   1
#5 809   1

答案 1 :(得分:2)

您需要使用ifelse()函数。

DF$ID <- ifelse(DF$INT == 1,  gsub("^9", "8", DF$ID), DF$ID)

使用dplyr

DF %>% 
   mutate(ID=ifelse(INT==1,gsub("^9","8",ID),ID))

这将在gsub的行上运行DF$INT == 1,如果它不是1,则它将保持不变。

您使用的if()函数:

if(DF$INT == "1") { }

不适用于data.frameif()函数仅用于 来检查某些内容(例如语句)是TRUE还是FALSE。例如:

if(use_new_function == "on"){ 
    run_new_function() 
}

答案 2 :(得分:1)

我们首先可以找到INT为1的索引,然后使用sub替换该索引处的值。

inds <- DF$INT == 1
DF$ID[inds] <- as.integer(sub("^9", "8", DF$ID[inds]))

DF
#   ID INT
#1 901   0
#2 802   1
#3 903   0
#4 804   1
#5 809   1

或者我们也可以使用ifelse

as.integer(ifelse(DF$INT == 1, sub("^9", "8", DF$ID), DF$ID))
#[1] 901 802 903 804 809

答案 3 :(得分:1)

substring可用于分配。根据“ INT”列并检查“ ID”的第一个字符是否为9('i1'),然后创建逻辑索引,然后使用substring将“ ID”的第一个字符分配给“ 8”

i1 <- as.logical(DF$INT) & substr(DF$ID, 1, 1) =='9'
substring(DF$ID[i1], 1, 1) <- '8'
DF
#   ID INT
#1 901   0
#2 802   1
#3 903   0
#4 804   1
#5 809   1

数据

DF <- structure(list(ID = c("901", "902", "903", "904", "909"), 
 INT = c(0, 
  1, 0, 1, 1)), row.names = c(NA, -5L), class = "data.frame")

答案 4 :(得分:0)

在示例数据DF中,两列都是数字,您可以简单地使用

DF$ID[DF$INT==1] <- DF$ID[DF$INT==1] - 100

如果列ID string ,则可以使用gsub,例如:

DF$ID <- as.character(DF$ID)
DF$ID[DF$INT==1] <- gsub("^9", "8", DF$ID[DF$INT==1])
#   ID INT
#1 901   0
#2 802   1
#3 903   0
#4 804   1
#5 809   1

将您的if(DF$INT == "1")放入数据子集[DF$INT==1]