我的数据框如下
df <- data.frame(c("Utility grid", "Grid connection", "Grid", "", "", "Dry-cell-torch", "Solar", ""), c("solar", "", "", "", "", "", "Dry-cell-torch", ""), c("", "fan", "TV", "", "Utility grid connection", "", "", "Unreachable"), c("", "radio", "", "", "", "", "", ""))
colnames(df) <- c(paste("de_", 1:4, sep=""))
我想在此数据框中附加第5列“de”,其中包含以下条件 -
条件1.如果所有行都为空(如第4行),则“de”应为0.
条件2.如果只有4行是非空白的,并且该值是“包含”“网格”而不区分大小写,或者是“无法访问”,或者是“干细胞火炬” “,那么”de“应为0。
条件3.否则“de”应为1
所需的“de”应为
df$de <- (c(1, 1, 1, 0, 0, 0, 1, 0))
请注意我的原始数据帧是600行和45列。我只是在这里放了一个子集,但这个子集说明了我想要完成的详尽条件。
所以我尝试了使用grepl的以下正则表达式(改编自你们其中一个人在stackoverflow中给出的一个解决方案,在一个不同但类似的问题中) -
df$de <- (!grepl("grid|Unreachable|Dry-cell-torch|^$",
apply(df,1,paste, collapse=""), ignore.case=TRUE))+0L
除了在第1行中我们说“实用网格”,在第二列中我有“太阳能”,在第一行我有“太阳能”的情况下,它给我de为0,而我需要1.我理解问题 - 如果存在网格,无法访问等之一,则应该与同一行中所有其他单元格的'和'条件组合应该为空,但我无法确定如何实现此
感谢您的帮助!
答案 0 :(得分:1)
这应该有效。我将默认值设置为1,然后将值设置为零(如果只有空格),或者除了一个之外只有空白,并且此异常值适合您的正则表达式。
df <- data.frame(c("Utility grid", "Grid connection", "Grid", "", "", "Dry-cell-torch", "Solar", ""), c("solar", "", "", "", "", "", "Dry-cell-torch", ""), c("", "fan", "TV", "", "Utility grid connection", "", "", "Unreachable"), c("", "radio", "", "", "", "", "", ""))
colnames(df) <- c(paste("de_", 1:4, sep=""))
df$de <- 1 # default value
blank_rows <- apply(df,1,function(row){sum(row == "")==ncol(df)-1})
regex_rows <- apply(df,1,function(row){sum(row == "")==ncol(df)-2 & any(grepl("grid|Unreachable|Dry-cell-torch|^$", row,ignore.case = TRUE))})
df$de[blank_rows | regex_rows] <- 0
# de_1 de_2 de_3 de_4 de
# 1 Utility grid solar 1
# 2 Grid connection fan radio 1
# 3 Grid TV 1
# 4 0
# 5 Utility grid connection 0
# 6 Dry-cell-torch 0
# 7 Solar Dry-cell-torch 1
# 8 Unreachable 0
答案 1 :(得分:1)
考虑明确分割条件:
f <- function(x) {
if ( all(x == '') ) 0
else if ( sum(x != '') == 1 ) {
if ( grepl('grid', tolower(x[x != ''])) |
(x[x != ''] %in% c('Unreachable', 'Dry-cell-torch')) ) 0
else 1
}
else 1
}
然后使用apply apply(df, 1, f)
我似乎得到了你想要的矢量:
> apply(df, 1, f)
[1] 1 1 1 0 0 0 1 0
<强>更新强>
可以使用另一个参数来索引f中所需的特定列。请注意,这不是一个强大的实现 - 设置错误的列会破坏它。
f <- function(x, columns) {
y <- x[columns]
if ( all(y == '') ) 0
else if ( sum(y != '') == 1 ) {
if ( grepl('grid', tolower(y[y != ''])) |
(y[y != ''] %in% c('Unreachable', 'Dry-cell-torch')) ) 0
else 1
}
else 1
}
然后使用apply apply(df, 1, f, columns = 1:4)
。只需将1:4替换为您想要的列。
更新2:
不确定我是否完全理解您的最新评论,但如果您想考虑多个“特殊”单元格,您可以考虑以下结构(虽然我不确定它是否会比“优雅”更加“优雅”你尝试了什么):
f <- function(x, columns) {
y <- x[columns]
n.not.blank <- sum( y != '' )
special <- c('Unreachable', 'Dry-cell-torch')
n.special <- sum( grepl('grid', tolower(y)) | (y %in% special) )
if (n.not.blank == 0) 0
else if (n.not.blank == n.special) 0
else 1
}
然后像以前一样使用apply。