R:按 space 拆分数据框行,删除公共元素,将不等长的列放入新的 df
R: split data frame rows by space, remove common elements, put unequal length columns in new df
假设,我有 df
两行字符串,我需要按 space 拆分,unlist,然后在列表中找到反交叉和重用。我可以通过单独处理每一行来蛮力做到这一点。问题是可以有超过 2 行等。到目前为止,我的工作解决方案如下,但必须有一种不访问每一行的更简单的方法。谢谢!!
df = structure(list(A = structure(1:2, .Label = c("R1", "R2"), class = "factor"),
B = c("a b c d e f g o l",
"b h i j k l m n o p q"
)), .Names = c("A", "B"), row.names = c(NA, -2L), class = "data.frame")
dat1 = unlist(strsplit(df[1,2]," "))
dat2 = unlist(strsplit(df[2,2]," "))
f <- function (...)
{
aux <- list(...)
ind <- rep(1:length(aux), sapply(aux, length))
x <- unlist(aux)
boo <- !(duplicated(x) | duplicated(x, fromLast = T))
split(x[boo], ind[boo])
}
excl = (f(dat1, dat2))
L <- list(excl[[1]],excl[[2]])
cfun <- function(L) {
pad.na <- function(x,len) {
c(x,rep("",len-length(x)))
}
maxlen <- max(sapply(L,length))
print(maxlen)
do.call(data.frame,lapply(L,pad.na,len=maxlen))
}
a = cfun(L)
我拥有的:
A B
1 Food a b c d e f g
2 HABA b h i j k l m n o p q
我得到的:
c..a....c....d....e....f....g.......... c..h....i....j....k....m....n....p....q..
1 a h
2 c i
3 d j
4 e k
5 f m
6 g n
7 p
8 q
编辑:目标是消除所有列中的公共元素。 IE。如果“4”出现在第 1 行并且在其他任何地方都可以看到 - 删除。新测试集:
df1 = structure(list(A = structure(1:3, .Label = c("R1", "R2", "R3"
), class = "factor"), B = c("1 4 78 5 4 6 7 0", "2 3 76 8 2 1 8 0",
"4 7 1 2")), .Names = c("A", "B"), row.names = c(NA, -3L), class = "data.frame")
建议代码的当前输出:
a b c
1 4 2 4
2 78 3 7
3 5 76 2
4 4 8 NA
5 6 2 NA
6 7 8 NA
7 0 0 NA
2、4 和 7 不应该存在,因为它们出现在不止 1 列中。底线 - 输出应仅在任何列中包含唯一的 numbers/elements。谢谢!!
这是一种使用 base R 的方法,可以避免大量当前代码
## split column B on the space character
s <- strsplit(df$B, " ")
## find the intersection of all s
r <- Reduce(intersect, s)
## iterate over s, removing the intersection characters in r
l <- lapply(s, function(x) x[!x %in% r])
## reset the length of each vector in l to the length of the longest vector
## then create the new data frame
setNames(as.data.frame(lapply(l, "length<-", max(lengths(l)))), letters[seq_along(l)])
# a b
# 1 a h
# 2 c i
# 3 d j
# 4 e k
# 5 f m
# 6 g n
# 7 <NA> p
# 8 <NA> q
我想这就是你拍摄的目的吧?
注意 lengths()
是 R 版本 3.2.0 基础包中的一个新函数,可以更快更有效地替代 sapply(x, length)
一个列表。
假设,我有 df
两行字符串,我需要按 space 拆分,unlist,然后在列表中找到反交叉和重用。我可以通过单独处理每一行来蛮力做到这一点。问题是可以有超过 2 行等。到目前为止,我的工作解决方案如下,但必须有一种不访问每一行的更简单的方法。谢谢!!
df = structure(list(A = structure(1:2, .Label = c("R1", "R2"), class = "factor"),
B = c("a b c d e f g o l",
"b h i j k l m n o p q"
)), .Names = c("A", "B"), row.names = c(NA, -2L), class = "data.frame")
dat1 = unlist(strsplit(df[1,2]," "))
dat2 = unlist(strsplit(df[2,2]," "))
f <- function (...)
{
aux <- list(...)
ind <- rep(1:length(aux), sapply(aux, length))
x <- unlist(aux)
boo <- !(duplicated(x) | duplicated(x, fromLast = T))
split(x[boo], ind[boo])
}
excl = (f(dat1, dat2))
L <- list(excl[[1]],excl[[2]])
cfun <- function(L) {
pad.na <- function(x,len) {
c(x,rep("",len-length(x)))
}
maxlen <- max(sapply(L,length))
print(maxlen)
do.call(data.frame,lapply(L,pad.na,len=maxlen))
}
a = cfun(L)
我拥有的:
A B
1 Food a b c d e f g
2 HABA b h i j k l m n o p q
我得到的:
c..a....c....d....e....f....g.......... c..h....i....j....k....m....n....p....q..
1 a h
2 c i
3 d j
4 e k
5 f m
6 g n
7 p
8 q
编辑:目标是消除所有列中的公共元素。 IE。如果“4”出现在第 1 行并且在其他任何地方都可以看到 - 删除。新测试集:
df1 = structure(list(A = structure(1:3, .Label = c("R1", "R2", "R3"
), class = "factor"), B = c("1 4 78 5 4 6 7 0", "2 3 76 8 2 1 8 0",
"4 7 1 2")), .Names = c("A", "B"), row.names = c(NA, -3L), class = "data.frame")
建议代码的当前输出:
a b c
1 4 2 4
2 78 3 7
3 5 76 2
4 4 8 NA
5 6 2 NA
6 7 8 NA
7 0 0 NA
2、4 和 7 不应该存在,因为它们出现在不止 1 列中。底线 - 输出应仅在任何列中包含唯一的 numbers/elements。谢谢!!
这是一种使用 base R 的方法,可以避免大量当前代码
## split column B on the space character
s <- strsplit(df$B, " ")
## find the intersection of all s
r <- Reduce(intersect, s)
## iterate over s, removing the intersection characters in r
l <- lapply(s, function(x) x[!x %in% r])
## reset the length of each vector in l to the length of the longest vector
## then create the new data frame
setNames(as.data.frame(lapply(l, "length<-", max(lengths(l)))), letters[seq_along(l)])
# a b
# 1 a h
# 2 c i
# 3 d j
# 4 e k
# 5 f m
# 6 g n
# 7 <NA> p
# 8 <NA> q
我想这就是你拍摄的目的吧?
注意 lengths()
是 R 版本 3.2.0 基础包中的一个新函数,可以更快更有效地替代 sapply(x, length)
一个列表。