我的数据框是这样的:
Name No
X 1
X 3
YYY 1
YYY 6
X 8
X 2
X 1
我想将最后3个X的名称更改为非X(例如X1)。基本上必须修改相同但不连续的值。在我的Name变量中有很多这种情况。在R中有什么办法吗?它与SAS中的not-sorted
非常相似。
非常感谢
答案 0 :(得分:4)
rle
在这里建议" 相同的值但不连续必须修改"
r <- rle(as.character(df$Name))
#Run Length Encoding
# lengths: int [1:3] 2 2 3
# values : chr [1:3] "X" "YYY" "X"
r$values <- make.unique(r$values,sep="")
inverse.rle(r)
#[1] "X" "X" "YYY" "YYY" "X1" "X1" "X1"
df$Name <- inverse.rle(r)
df
# Name No
#1 X 1
#2 X 3
#3 YYY 1
#4 YYY 6
#5 X1 8
#6 X1 2
#7 X1 1
答案 1 :(得分:1)
我们只使用简单的base R
函数
df1$Name <- with(df1, paste0(Name, cumsum(c(TRUE, Name[-1]!= Name[length(df1)])),
Name, FUN = function(x) {
x1 <- match(x, unique(x))-1
replace(x1, !x1, "")})))
df1
# Name No
#1 X 1
#2 X 3
#3 YYY 1
#4 YYY 6
#5 X1 8
#6 X1 2
#7 X1 1
或将rle
与ave
inverse.rle(within.list(rle(df1$Name), {
v1 <- ave(seq_along(values), values, FUN = seq_along)-1
values <- paste0(values, replace(v1, !v1, ''))}))
#[1] "X" "X" "YYY" "YYY" "X1" "X1" "X1"
注意:以上解决方案提供了帖子中提到的OP的预期输出,但不包含任何.
或另一种选择是
library(data.table)
setDT(df1)[, gr := rleid(Name)]
unique(df1[, c("Name", "gr"), with = FALSE])[,
Name := make.unique(Name)][df1, on = 'gr'][, 2:3 := NULL][]
# Name No
#1: X 1
#2: X 3
#3: YYY 1
#4: YYY 6
#5: X.1 8
#6: X.1 2
#7: X.1 1