R - 根据标准在一行中查找值
R - Finding Values in a Row based on Criteria
我有一个具有两个基本条件的数据集,我试图根据它们在数据框中的位置来匹配这些值。这是一个例子:
Row Cond Y
1 n 350
2 n 354
3 t 375
4 n 300
5 n 157
6 t 810
7 n 214
8 n 243
9 n 345
10 n 216
11 n 198
12 t 870
我想将 "n" 的每个值与附近的 "t" 值相匹配(即,彼此相隔 5 行以内)。然后,我想从 "t" 中减去 "n" 的值。在上面的示例中,我们的第 1 行将与第 3 行匹配,我们得出的值为 25 (375 - 350)。如果该行在两个 "t" 行之间等距,如果可能的话,我想默认为较早的 "t" 行。理想情况下,我会在适当的情况下使用这些差异分数创建一个新向量,以便 "NA" 或“0”出现在具有 "t" 条件的行中。所以这看起来像:
Result
25
21
NA
75
653
NA
596
567
465
654
672
NA
有没有办法在 R 中实现这个?我已经根据条件(例如“<”或“==”)尝试了一些子集,但我想知道我是否以错误的方式处理它!任何见解将不胜感激! :)
getclosest <- function(df, i) {
if (as.character(df$Cond[[i]]) == "t") {
return (NA)
} else {
# df$Y[i]
below <- NA
above <- NA
aj <- NA
bj <- NA
for (j in 1:5) {
pos <- i - j
if (pos < 1) break
if (df$Cond[pos] == "t") {
below <- df$Y[pos]
bj <- j
break
}
}
for (j in 1:5) {
pos <- i + j
if (pos > nrow(df)) break
if (df$Cond[pos] == "t") {
above <- df$Y[pos]
aj <- j
break
}
}
temp = NA
tempb = NA
if (is.na(above) && is.na(below)) {
return(NA)
}
if (!is.na(below) && !is.na(above)) {
if (aj < bj) {
return(abs(above - df$Y[i]))
} else {
return(abs(below - df$Y[i]))
}
}
if (!is.na(below)) {
tempb <- abs(below - df$Y[i])
return (tempb)
}
if (!is.na(above)) {
tempa <- abs(above - df$Y[i])
return(tempa)
}
return (NA)
}
}
df <- data.frame(Cond=c('n', 'n', 't','n','n','t','n','n','n','n','n','t'), Y=c(350,354,375,300,157,810,214,243,345,216,198,870))
v <- c() # length=nrow(df))
for (i in 1:nrow(df)) {
v[i] <- getclosest(df, i)
}
我有一个具有两个基本条件的数据集,我试图根据它们在数据框中的位置来匹配这些值。这是一个例子:
Row Cond Y
1 n 350
2 n 354
3 t 375
4 n 300
5 n 157
6 t 810
7 n 214
8 n 243
9 n 345
10 n 216
11 n 198
12 t 870
我想将 "n" 的每个值与附近的 "t" 值相匹配(即,彼此相隔 5 行以内)。然后,我想从 "t" 中减去 "n" 的值。在上面的示例中,我们的第 1 行将与第 3 行匹配,我们得出的值为 25 (375 - 350)。如果该行在两个 "t" 行之间等距,如果可能的话,我想默认为较早的 "t" 行。理想情况下,我会在适当的情况下使用这些差异分数创建一个新向量,以便 "NA" 或“0”出现在具有 "t" 条件的行中。所以这看起来像:
Result
25
21
NA
75
653
NA
596
567
465
654
672
NA
有没有办法在 R 中实现这个?我已经根据条件(例如“<”或“==”)尝试了一些子集,但我想知道我是否以错误的方式处理它!任何见解将不胜感激! :)
getclosest <- function(df, i) {
if (as.character(df$Cond[[i]]) == "t") {
return (NA)
} else {
# df$Y[i]
below <- NA
above <- NA
aj <- NA
bj <- NA
for (j in 1:5) {
pos <- i - j
if (pos < 1) break
if (df$Cond[pos] == "t") {
below <- df$Y[pos]
bj <- j
break
}
}
for (j in 1:5) {
pos <- i + j
if (pos > nrow(df)) break
if (df$Cond[pos] == "t") {
above <- df$Y[pos]
aj <- j
break
}
}
temp = NA
tempb = NA
if (is.na(above) && is.na(below)) {
return(NA)
}
if (!is.na(below) && !is.na(above)) {
if (aj < bj) {
return(abs(above - df$Y[i]))
} else {
return(abs(below - df$Y[i]))
}
}
if (!is.na(below)) {
tempb <- abs(below - df$Y[i])
return (tempb)
}
if (!is.na(above)) {
tempa <- abs(above - df$Y[i])
return(tempa)
}
return (NA)
}
}
df <- data.frame(Cond=c('n', 'n', 't','n','n','t','n','n','n','n','n','t'), Y=c(350,354,375,300,157,810,214,243,345,216,198,870))
v <- c() # length=nrow(df))
for (i in 1:nrow(df)) {
v[i] <- getclosest(df, i)
}