R语言筛选DataFrame:保留指定列含特定数值范围的行
问题
需要对包含92列、约2000行的DataFrame进行子集筛选,仅保留以'daysbetween'开头的列(共50列)中任意一列存在-30到30之间数值的行。尝试使用以下代码:
data <- crf1 %>% filter(if_any(starts_with("daysbetween"), ~ . > -30 & ~. < 30 ))
出现报错:
Error in `filter()`: ℹ In argument: `... | daysbetweenV1312 > -30 & (~ . < 30)`. Caused by error in `daysbetweenV21 > -30 & (~ . < 30)`: ! operations are possible only for numeric, logical or complex types
附数据样本:
structure(list(V1 = c("00006", "00009", "00013", "00017", "00040", "00042", "00043", "00051", "00061", "00068"), V2 = structure(c(18750, 18745, 18753, 18922, 18898, 18925, 19018, 18726, 18977, 18766 ), class = "Date"), V3 = structure(c(18917, 18904, 19146, 18922, 18898, 19018, 19196, 18959, 18946, 18945), class = "Date"), V4 = structure(c(18823, 18905, 19275, 19187, 19219, 19134, 19331, 18885, 18922, 19275 ), class = "Date"), V5 = structure(c(18972, 19185, NA, NA, NA, 19349, 19289, 19063, 19149, 18400), class = "Date"), V6 = structure(c(19352, NA, NA, NA, NA, NA, NA, 19035, 19028, NA), class = "Date"), V7 = structure(c(NA, NA, NA, NA, NA, NA, NA, 19197, NA, NA), class = "Date"), V8 = structure(c(NA, NA, NA, NA, NA, NA, NA, 19411, NA, NA), class = "Date"), V9 = structure(c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), class = "Date"), V10 = structure(c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), class = "Date"), V11 = structure(c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), class = "Date"), V12 = structure(c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), class = "Date"), V13 = structure(c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), class = "Date"), V14 = structure(c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), class = "Date"), daysbetweenV21 = structure(c(167, 159, 393, 0, 0, 93, 178, 233, -31, 179), class = "difftime", units = "days"), daysbetweenV22 = structure(c(73, 160, 522, 265, 321, 209, 313, 159, -55, 509), class = "difftime", units = "days")), row.names = c(NA, 10L), class = "data.frame")
注:V1至V14列无需参与筛选,仅关注以'daysbetween'开头的列。
解决方案
报错原因
daysbetween开头的列属于difftime类型,直接与整数进行比较会触发类型不兼容错误——R中difftime是特殊的时间差类,必须先转换为数值类型才能进行数值比较。
修正代码
方式1:筛选时即时转换类型
适合仅需临时筛选、不需要修改原数据列类型的场景:
data <- crf1 %>% filter(if_any(starts_with("daysbetween"), ~ as.numeric(.) > -30 & as.numeric(.) < 30))
方式2:先转换列类型再筛选
适合后续仍需对这些列进行数值操作的场景:
# 批量转换difftime列为数值型 crf1 <- crf1 %>% mutate(across(starts_with("daysbetween"), as.numeric)) # 执行筛选 data <- crf1 %>% filter(if_any(starts_with("daysbetween"), ~ . > -30 & . < 30))
效果验证
用提供的样本数据测试,上述代码会保留daysbetweenV21值为0的第4、5行,符合“任意一列存在-30到30之间数值”的筛选需求。
内容的提问来源于stack exchange,提问作者Debbie Oomen
相关产品推荐
相关产品推荐

