数据:
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解决方案,但是我不确定如何根据一个列对两个列进行突变。任何见识将不胜感激。
答案 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