我试图覆盖excel中的逻辑,但是因为我不是excel的专业人员而失败。
以下是我的数据:
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
1 12 3 3 4 5 6 7 7 7 7 7 7 7 7 7
2 1 4 5 5 5 5 5 5 6 7 8 8 8 8 8
3 3 4 4 4 4 45 32 57 23 23 23 23 23 23 23
如您所见,在第一行中,从最后一列开始,有多个7&#39。相似,对于从最后一列开始的第二行 有多个8&s;对于row3,有多个23&.s。
我想将7&8,8&23和23的多个列替换为#N / A,并且只保留结果中的前7个。 我用一个简单的逻辑尝试了它,其中IF(C15<> C14,C15," N / A"),然而这个逻辑失败了,因为它也转换了行级别的先前重复值
以下是我寻找最终结果的方法。
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
1 12 3 3 4 5 6 7 #N/A #N/A #N/A #N/A #N/A #N/A #N/A #N/A
2 1 4 5 5 5 5 5 5 6 7 8 #N/A #N/A #N/A #N/A
3 3 4 4 4 4 45 32 57 23 #N/A #N/A #N/A #N/A #N/A #N/A
我可以在Excel中执行此操作,还是需要在R中找到一些代码?
任何线索都会受到赞赏。
谢谢, 杰
数据:
df <- structure(list(C1 = c(12, 1, 3), C2 = c(3, 4, 4), C3 = c(3, 5, 4),
C4 = c(4, 5, 4), C5 = c(5, 5, 4), C6 = c(6, 5, 45),
C7 = c(7, 5, 32), C8 = c(7, 5, 57), C9 = c(7, 6, 23),
C10 = c(7, 7, 23), C11 = c(7, 8, 23), C12 = c(7, 8, 23),
C13 = c(7, 8, 23), C14 = c(7, 8, 23), C15 = c(7, 8, 23)),
.Names = c("C1", "C2", "C3", "C4", "C5",
"C6", "C7", "C8", "C9", "C10",
"C11", "C12", "C13", "C14", "C15"),
row.names = c(NA, -3L), class = "data.frame")
答案 0 :(得分:2)
以下是使用rleid
中的data.table
的R解决方案:
library(data.table)
df[t(apply(df, 1, function(x) shift(rleid(x) == max(rleid(x)))))] <- NA
<强>结果:强>
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
1 12 3 3 4 5 6 7 NA NA NA NA NA NA NA NA
2 1 4 5 5 5 5 5 5 6 7 8 NA NA NA NA
3 3 4 4 4 4 45 32 57 23 NA NA NA NA NA NA
请注意,即使重复整数出现在每行中没有连接到最后重复序列的任何位置,这也是有效的。
数据:强>
df = structure(list(C1 = c(12L, 1L, 3L), C2 = c(3L, 4L, 4L), C3 = c(3L,
5L, 4L), C4 = c(4L, 5L, 4L), C5 = c(5L, 5L, 4L), C6 = c(6L, 5L,
45L), C7 = c(7L, 5L, 32L), C8 = c(7L, 5L, 57L), C9 = c(7L, 6L,
23L), C10 = c(7L, 7L, 23L), C11 = c(7L, 8L, 23L), C12 = c(7L,
8L, 23L), C13 = c(7L, 8L, 23L), C14 = c(7L, 8L, 23L), C15 = c(7L,
8L, 23L)), .Names = c("C1", "C2", "C3", "C4", "C5", "C6", "C7",
"C8", "C9", "C10", "C11", "C12", "C13", "C14", "C15"), class = "data.frame", row.names = c(NA,
-3L))
答案 1 :(得分:1)
使用基础R,您可以像下面这样做 这是该函数的第三个版本,感谢@useR在某些用例中指出其他函数的错误结果。
fun <- function(x, n){
r <- rle(x)
n <- length(x)
x[(n - r$lengths[length(r$lengths)] + 2):n] <- NA
x
}
x <- c(12,3,3,4,5,6,7,7,7,7,7,7,7,7,7)
fun(x)
#[1] 12 3 3 4 5 6 7 NA NA NA NA NA NA NA NA
y <- c(12,7,7,4,5,6,7,7,7,7,7,7,7,7,7)
fun(y)
#[1] 12 7 7 4 5 6 7 NA NA NA NA NA NA NA NA
现在使用data.frame
。
dat[] <- t(apply(dat, 1, fun))
# C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
#1 12 3 3 4 5 6 7 NA NA NA NA NA NA NA NA
#2 1 4 5 5 5 5 5 5 6 7 8 NA NA NA NA
#3 3 4 4 4 4 45 32 57 23 NA NA NA NA NA NA
数据。
dat <- read.csv(text = "
C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15
12,3,3,4,5,6,7,7,7,7,7,7,7,7,7
1,4,5,5,5,5,5,5,6,7,8,8,8,8,8
3,4,4,4,4,45,32,57,23,23,23,23,23,23,23
")
答案 2 :(得分:1)
数据:
$('#add')
代码:
df1 <- read.table(text='C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15
12,3,3,4,5,6,7,7,7,7,7,7,7,7,7
1,4,5,5,5,5,5,5,6,7,8,8,8,8,8
3,4,4,4,4,45,32,57,23,23,23,23,23,23,23', sep = ",", header = TRUE, stringsAsFactors = FALSE)
输出:
apply(df1, 1, function(x) {
x <- rle(x)
len_x <- length(x$lengths)
if( (x$lengths)[len_x] > 1 ){ # check for end sequence
x <- list(lengths = c(x$lengths[-len_x], 1, x$lengths[len_x]- 1 ),
values = c(x$values, NA))
}
inverse.rle(x)
})
答案 3 :(得分:0)
在:
代码:
Sub marine()
For i = 2 To 4
For j = 15 To 2 Step -1
If Cells(i, j).Value = Cells(i, j - 1).Value Then
Cells(i, j).Value = "#N/A"
Else
Exit For
End If
Next j
Next i
End Sub
之后:
答案 4 :(得分:0)
这只使用一个循环:
Sub nadup()
With Worksheets("Sheet5") 'change to your sheet
Dim i As Long
For i = 2 To 4
Dim t As Long
t = Application.Match(.Cells(i, 15), Range(i & ":" & i), 0)
If t < 14 Then
.Range(.Cells(i, t + 1), .Cells(i, 15)).Value = "N/A"
ElseIf t = 14 Then
.Cells(i, 15) = "N/A"
End If
Next i
End With
End Sub
答案 5 :(得分:0)
使用数组
Option Explicit
Public Sub ReplaceItems()
Dim arr(), arr2(), i As Long, j As Long
With ActiveSheet
arr() = .Range("A1:O3").Value
For i = LBound(arr, 1) To UBound(arr, 1)
ReDim arr2(1 To UBound(arr, 2))
For j = LBound(arr, 2) To UBound(arr, 2)
If IsError(Application.Match(arr(i, j), arr2, 0)) Then
arr2(j) = arr(i, j)
Else
Select Case arr(i, j)
Case 7, 8, 23
arr2(j) = "#N/A"
Case Else
arr2(j) = arr(i, j)
End Select
End If
Next
.Range("A" & i).Resize(1, UBound(arr2)).Value = arr2
Next i
End With
End Su