如果A列满足条件,则在A和B列中粘贴前导零

时间:2020-09-01 01:42:18

标签: r loops

数据:

A            B
"2058600192", "2058644"
"4087600101", "4087601"
"30138182591","30138011"

如果列A为10个字符,我想在A和B列前添加一个前导0。

这是我到目前为止写的:

for (i in 1:nrow(data)) {
    if (nchar(data$A[i]) == 10) {  
      data$A[i] <- paste0(0, data$A)
      data$B[i] <- paste0(0, data$B)  
    } 
}

但是我收到以下警告:

  number of items to replace is not a multiple of replacement length

我也尝试过使用dplyr解决方案,但是我不确定如何根据一个列对两个列进行突变。任何见识将不胜感激。

5 个答案:

答案 0 :(得分:1)

您可以使用多列replace来获取字符数等于10的索引,并lapply获得这些值。

inds <- nchar(df$A) == 10
df[] <- lapply(df, function(x) replace(x, inds, paste0('0', x[inds])))
#If you want to replace only specific columns
#df[c('A', 'B')] <- lapply(df[c('A', 'B')], function(x) 
#                         replace(x, inds, paste0('0', x[inds])))
df

#            A        B
#1 02058600192 02058644
#2 04087600101 04087601
#3 30138182591 30138011

数据

df <- structure(list(A = c(2058600192, 4087600101, 30138182591), B = c(2058644L, 
4087601L, 30138011L)), class = "data.frame", row.names = c(NA, -3L))

答案 1 :(得分:1)

您的解决方案已经相当不错。您刚刚犯了一些非常小的错误。该代码将提供正确的输出:

data <- data.frame(A = c("2058600192","4087600101","30138182591"), B = c("2058644","4087601","30138011"))

for (i in 1:nrow(data)) {
  
  if (nchar(data$A[i]) == 10) {
    
    data$A[i] <- paste0(0, data$A[i])
    data$B[i] <- paste0(0, data$B[i])
    
  } 
}

唯一的区别是data$A[i] <- paste0(0, data$A[i])而不是data$A[i] <- paste0(0, data$A)。如果没有[i],您将尝试添加整个列。

答案 2 :(得分:1)

只要您有兴趣使用dplyr,这是使用transmute的另一种解决方案。

df %>%
  # Need to transmute B first, so that nchar is evaluated on the original A column and not on the one with leading zeros
  transmute(B = ifelse(nchar(A) == 10, paste0(0, B), B),
            A = ifelse(nchar(A) == 10, paste0(0, A), A)) %>%
  # Just change the order of the columns to the original one
  select(A,B)

答案 3 :(得分:1)

另一种尝试的方式

library(dplyr)
library(stringr)
df %>% 
  mutate(A = ifelse(str_length(A) == 10, str_pad(A, width = 11, side = "left", pad = 0), A),
         B = ifelse(grepl("^0", A), paste0("0", B), B))
#       A        B
# 1 02058600192 02058644
# 2 04087600101 04087601
# 3 30138182591 30138011
  • str_length检测字符串的长度
  • 您可以使用str_pad添加前导零。有关str_pad() here
  • 的更多信息
  • 我们可以使用grepl来检测A列中带有前导零的字符串,并在B列中添加前导零。

答案 4 :(得分:0)

您可以在此处使用ifelse矢量化函数:

data$A <- ifelse(nchar(data$A) == 10, paste0("0", data$A), data$A)
data$B <- ifelse(nchar(data$B) == 10, paste0("0", data$B), data$B)
data

            A        B
1 02058600192  2058644
2 04087600101  4087601
3 30138182591 30138011
相关问题