在以下示例数据帧中:
# generate example data frame
data <- data.frame(matrix(data=c("a","b","c","d","e","f"), nrow=70, ncol=5))
data <- apply(data,1, function(x) {paste(x, collapse = " > ")})
data <- data.frame(id=1:length(data), x = data)
data$x <- as.character(data$x)
> head(data)
id x
1 1 a > e > c > a > e
2 2 b > f > d > b > f
3 3 c > a > e > c > a
4 4 d > b > f > d > b
5 5 e > c > a > e > c
6 6 f > d > b > f > d
x列中的某些属性是预先已知的,但并非所有属性都是已知的。
已知的属性将替换为单独的名称。在本例中,已知属性集为{"a"、"c"、"f"}。
所有不属于该集合的属性都不是预先已知的,应该用NA
替换。
步骤1:替换属性{"a"、"c"、"f"}
# substitute all relevant attributes with according Names
data$x <- gsub("a", "Anton",data$x)
data$x <- gsub("c", "Chris",data$x)
data$x <- gsub("f", "Flo",data$x)
数据帧现在看起来是:
> head(data)
id x
1 1 Anton > e > Chris > Anton > e
2 2 b > Flo > d > b > Flo
3 3 Chris > Anton > e > Chris > Anton
4 4 d > b > Flo > d > b
5 5 e > Chris > Anton > e > Chris
6 6 Flo > d > b > Flo > d
步骤2:用NA
替换{"Anton"、"Chris"、"Flo"}以外的所有属性
这是我需要帮助的地方
我的想法是利用正则表达式,将不在{"Anton"、"Chris"、"Flo"、">"}中的每个值/字符串替换为"NA"。
在我的实际问题中,我不知道值{"b"、"d"、"e"}和属性可以采用长度大于1的任何值或单词。此外,未知集的值可以随时间变化。因此,如果函数将在以后的实例中执行,则可能会有新的未知值。
结果:生成的数据帧应该看起来像:
> head(data)
id x
1 1 Anton > NA > Chris > Anton > NA
2 2 NA > Flo > NA > NA > Flo
3 3 Chris > Anton > NA > Chris > Anton
4 4 NA > NA > Flo > NA > NA
5 5 NA > Chris > Anton > NA > Chris
6 6 Flo > NA > NA > Flo > NA
感谢您的帮助!
您可以从qdap
尝试mgsub
library(qdap)
data$x <- mgsub(c('a', 'c', 'f', 'd', 'e', 'b'),
c('Anton', 'Chris', 'Flo', 'NA', 'NA', 'NA'), data$x)
head(data,3)
# id x
#1 1 Anton > NA > Chris > Anton > NA
#2 2 NA > Flo > NA > NA > Flo
#3 3 Chris > Anton > NA > Chris > Anton
更新
假设我们只知道要被其他元素"v3"替换的元素列表("v1"),那么我们可以通过用gsub
删除"v1"中的元素和"x"列的"punct"字符来获得其他元素("v2")。使用此信息输入mgsub
v1 <- c('a', 'c', 'f')
v2 <- unique(scan(text=gsub(paste(c(v1,"[[:punct:]]+"),
collapse="|"), "", data$x), what='', quiet=TRUE))
v3 <- c('Anton', 'Chris', 'Flo')
data$x <- mgsub(c(v1, v2), c(v3, rep("NA", length(v2))), data$x)
head(data,3)
# id x
#1 1 Anton > NA > Chris > Anton > NA
#2 2 NA > Flo > NA > NA > Flo
#3 3 Chris > Anton > NA > Chris > Anton
更新2
你也可以在不使用任何外部包的情况下做到这一点
names(v3) <- v1
data$x <- sapply(strsplit(data$x, ' > '), function(x)
paste(v3[x], collapse=" > "))
head(data,3)
# id x
#1 1 Anton > NA > Chris > Anton > NA
#2 2 NA > Flo > NA > NA > Flo
#3 3 Chris > Anton > NA > Chris > Anton
这一行将每个单词字符与所示列表的名称进行匹配,并将匹配项替换为与该名称相关的值。如果不匹配,则使用NA
作为替换值:
library(gsubfn)
data$x <- gsubfn("\w", list(a = "Anton", c = "Chris", f = "Flo", NA), data$x)
给予:
> head(data)
id x
1 1 Anton > NA > Chris > Anton > NA
2 2 NA > Flo > NA > NA > Flo
3 3 Chris > Anton > NA > Chris > Anton
4 4 NA > NA > Flo > NA > NA
5 5 NA > Chris > Anton > NA > Chris
6 6 Flo > NA > NA > Flo > NA