假设我有一个如下所示的数据框,我需要识别每行,其中一个或多个缺失值 (NA) 后跟至少一个有效值(任何数字)。你可以帮我吗?
a <- c(1, 'S06.4', 6.7, 7.0, 6.5, 7.0, 7.2, NA, NA, 6.6,6.7)
b <- c(2 ,'S06.2' ,5.0, NA, 4.9, 7.8, 9.3, 8.0, 7.8, 8.0,NA)
c <- c(3, 'S06.5', 7.0, 5.5, NA, NA, 7.2, 8.0, 7.6, NA,6.7)
d <- c(4, 'S06.5', 7.0, 7.0, 7.0, 6.9, 6.8, 9.0, 6.0, 6.6,6.7)
e <- c(5, 'S06.1', 6.7, NA, NA, NA, NA, NA, NA, NA,NA)
df <- data.frame(rbind(a,b,c,d,e))
colnames(df) <- c('id','dx','dia01','dia02','dia03','dia04','dia05','dia06','dia07','dia08','dia09')
下面是一个使用rle()
的解决方案:
(我使用了Jaap答案中的数据定义)
df <- structure(list(id = c("1", "2", "3", "4", "5"),
dx = c("S06.4", "S06.2", "S06.5", "S06.5", "S06.1"),
dia01 = c(6.7, 5, 7, 7, 6.7),
dia02 = c(7, NA, 5.5, 7, NA),
dia03 = c(6.5, 4.9, NA, 7, NA),
dia04 = c(7, 7.8, NA, 6.9, NA),
dia05 = c(7.2, 9.3, 7.2, 6.8, NA),
dia06 = c(NA, 8, 8, 9, NA),
dia07 = c(NA, 7.8, 7.6, 6, NA),
dia08 = c(6.6, 8, NA, 6.6, NA),
dia09 = c(6.7, NA, 6.7, 6.7, NA)),
.Names = c("id", "dx", "dia01", "dia02", "dia03", "dia04", "dia05", "dia06", "dia07", "dia08", "dia09"),
row.names = c("a", "b", "c", "d", "e"),
class = "data.frame")
R <- apply(is.na(df[-(1:2)]), 1, rle)
id.row <- function(r) {
first.na <- which(r$value)[1]
if (is.na(first.na)) return(FALSE)
if (first.na==length(r$value)) return(FALSE)
return(TRUE)
}
sapply(R, id.row)
#> sapply(R, id.row)
# a b c d e
# TRUE TRUE TRUE FALSE FALSE
另一个想法是使用< code>apply和margin 1
遍历每一行,并将NA的最小索引与非NA的最大索引进行比较,即
#convert to numeric first to capture only valid numbers (as in @Jaap's answer)
df[-c(1,2)] <- lapply(df[-c(1,2)], function(x) as.numeric(as.character(x)))
apply(d1, 1, function(i) min(which(is.na(i))) < max(which(!is.na(i))))
# a b c d e
# TRUE TRUE TRUE FALSE FALSE
#or
df[apply(d1, 1, function(i) min(which(is.na(i))) < max(which(!is.na(i)))),]
这给了,
id dx dia01 dia02 dia03 dia04 dia05 dia06 dia07 dia08 dia09
a 1 S06.4 6.7 7 6.5 7 7.2 <NA> <NA> 6.6 6.7
b 2 S06.2 5 <NA> 4.9 7.8 9.3 8 7.8 8 <NA>
c 3 S06.5 7 5.5 <NA> <NA> 7.2 8 7.6 <NA> 6.7
使用:
df[rowSums(is.na(df[,3:10]) * !is.na(df[,4:11])) > 0,]
你得到:
id dx dia01 dia02 dia03 dia04 dia05 dia06 dia07 dia08 dia09
a 1 S06.4 6.7 7 6.5 7 7.2 <NA> <NA> 6.6 6.7
b 2 S06.2 5 <NA> 4.9 7.8 9.3 8 7.8 8 <NA>
c 3 S06.5 7 5.5 <NA> <NA> 7.2 8 7.6 <NA> 6.7
这是做什么的:
是。na(df[,3:10])
检查<code>dia01</code>到<code>dia08</code>列中的哪个值是<code>na</code>,并返回逻辑矩阵
df[,3:10]
每行中的下一个值执行相同操作,并返回逻辑矩阵rowSums
,您可以检查每行中是否至少满足一次条件针对您的评论:如果您想确保NA
后跟一个数值,您可以更改上述解决方案以:
# first convert the 'dia*''-columns to numeric
df[-c(1,2)] <- lapply(df[-c(1,2)], function(x) as.numeric(as.character(x)))
# then do the same because values that can't converted to numeric will give NA
df[rowSums(is.na(df[,3:10]) * !is.na(df[,4:11])) > 0,]
或者不先转换成数字:
df[rowSums(is.na(df[,3:10]) * !is.na(sapply(df[4:11], function(x) as.numeric(as.character(x))))) > 0,]
注意:
使用用于构造示例数据的方法,最终将得到所有因子列。我想你不希望这样。
格式可能正确的示例数据集将是:
df <- structure(list(id = c("1", "2", "3", "4", "5"),
dx = c("S06.4", "S06.2", "S06.5", "S06.5", "S06.1"),
dia01 = c(6.7, 5, 7, 7, 6.7),
dia02 = c(7, NA, 5.5, 7, NA),
dia03 = c(6.5, 4.9, NA, 7, NA),
dia04 = c(7, 7.8, NA, 6.9, NA),
dia05 = c(7.2, 9.3, 7.2, 6.8, NA),
dia06 = c(NA, 8, 8, 9, NA),
dia07 = c(NA, 7.8, 7.6, 6, NA),
dia08 = c(6.6, 8, NA, 6.6, NA),
dia09 = c(6.7, NA, 6.7, 6.7, NA)),
.Names = c("id", "dx", "dia01", "dia02", "dia03", "dia04", "dia05", "dia06", "dia07", "dia08", "dia09"),
row.names = c("a", "b", "c", "d", "e"),
class = "data.frame")
所提出的方法也适用于此。
正如@Frank在评论中指出的那样,最好以长格式存储您的数据。使用:
library(data.table)
setDT(df)[, 3:11 := lapply(.SD, function(x) as.numeric(as.character(x))), .SDcols = 3:11][]
melt(df, id = 1:2)[, if(any(is.na(value) & !is.na(shift(value, type = 'lead')))) .SD, by = .(id, dx)]
你得到:
id dx variable value
1: 1 S06.4 dia01 6.7
2: 1 S06.4 dia02 7.0
3: 1 S06.4 dia03 6.5
4: 1 S06.4 dia04 7.0
5: 1 S06.4 dia05 7.2
6: 1 S06.4 dia06 NA
7: 1 S06.4 dia07 NA
8: 1 S06.4 dia08 6.6
9: 1 S06.4 dia09 6.7
10: 2 S06.2 dia01 5.0
11: 2 S06.2 dia02 NA
12: 2 S06.2 dia03 4.9
13: 2 S06.2 dia04 7.8
14: 2 S06.2 dia05 9.3
15: 2 S06.2 dia06 8.0
16: 2 S06.2 dia07 7.8
17: 2 S06.2 dia08 8.0
18: 2 S06.2 dia09 NA
19: 3 S06.5 dia01 7.0
20: 3 S06.5 dia02 5.5
21: 3 S06.5 dia03 NA
22: 3 S06.5 dia04 NA
23: 3 S06.5 dia05 7.2
24: 3 S06.5 dia06 8.0
25: 3 S06.5 dia07 7.6
26: 3 S06.5 dia08 NA
27: 3 S06.5 dia09 6.7
另一种选择是:
setDT(df)[, 3:11 := lapply(.SD, function(x) as.numeric(as.character(x))), .SDcols = 3:11][]
df[unique(melt(df, id = 1:2)[, .I[is.na(value) & !is.na(shift(value, type = 'lead'))], by = .(id, dx)], by = 'id')[,'id'], on = 'id']
然而,这种方法的结果仍然是广泛的格式,如本答案的第一部分所述。
问题内容: 我有一个sql表,用于存储股票的每日价格。收市后每天都会插入新的记录。我想找到价格连续上涨的股票。 该表有很多列,但这是相关的子集: 该列是主键。 在表中,股票编号1的收盘价每天都在增加。股票ID 3的波动很大,股票ID 2的价格在最后一天下跌。 我正在寻找这样的结果: 如果您可以获得带有连续条纹的日期的输出,那就更好了: 价格开始上涨的时间,牛市实际上结束的时间。 我认为这不是一个容
问题内容: 如果我有串,我要检查,如果它作为一个连续存在 串 中,我可以使用: 在非连续子 序列 的情况下,我可以使用什么?例: 问题答案: 我不知道是否有内置功能,但是手动操作相当简单
问题内容: 我有带有示例数据的下表: 桌子: 样本数据: 预期结果 : 注意 :我试图找出节点的连通性以及节点之间的长度之和。 我尝试以下查询相同: 我的尝试 : 无法获得预期的结果。 问题答案: 我很确定您需要递归CTE。但是,您的样本结果没有任何意义。 以下内容基本上可以满足您的要求: 这是一个。
谈到R编码,我目前有点墨守成规。我一直在尝试使用mutate、seq和rep函数来生成一个新列,该列迭代多个列值和不同的条件,但结果并不正确。下面是我的一些数据片段: 我希望按类型和特征 ID 对 lipidName 进行分组,然后查看类型特征 ID2,而不是不正确的数据表。如果它们具有相同的类型和特征 ID,则将它们计为脂质名称的相同脂质。如果它们具有相同的类型和特征ID2,则将它们计为脂质名称
问题内容: 在[成员]表中,某些行的列值相同。 有些人使用了不同的login_id,但是使用了相同的电子邮件地址,因此在此列上未设置唯一约束。现在,我需要查找这些行,并查看是否应将其删除。 我应该使用什么SQL语句查找这些行?(MySQL 5) 问题答案: 此查询将为您提供电子邮件地址及其使用次数的列表,最常用的地址在前。 如果要完整行:
问题内容: 我试图找到具有重复值,但仅基于选定的列数,而不是单个列或整个行的行。例如,如果我的表如下所示: 我的问题是: 查找行的“地址和状态”字段与另一行的“地址和状态”字段匹配的行的所有ID。 该查询的答案将是: 有任何想法吗? 意见建议: 如何从单个表中选择同一行中的多列值 问题答案: 请尝试以下方法: