我有2个因子列,我想创建一个第三列,该列告诉我第二个列具有什么,而第一列没有。
这与这个post非常相似,但是我很难从df
转到使用setdiff()
函数。
例如:
library(dplyr)
y1 <- c("a.b.","a.","b.c.d.")
y2 <- c("a.b.c.","a.b.","b.c.d.")
df <- data.frame(y1,y2)
列
y1
具有a.b.
,列y2
具有a.b.c.
。我希望有三分之二的列返回c.
或仅返回c
。> df
y1 y2 col3
1 a.b. a.b.c. c.
2 a. a.b. b.
3 b.c.d. b.c.d.
我认为这应该是
strsplit
和setdiff
的组合,但我无法使其正常工作。我尝试将
factor
转换为character
,然后尝试将strsplit()
应用于结果,但是输出对我来说似乎很奇怪。似乎已在列表中创建了一个列表,这使得很难传递给setdiff()
#convert factor to character
df <- df %>% mutate_if(is.factor, as.character)
lapply(df$y1,function(x)(strsplit(x,split = "[.]")))
> lapply(df$y1,function(x)(strsplit(x,split = "[.]")))
[[1]]
[[1]][[1]]
[1] "a" "b"
[[2]]
[[2]][[1]]
[1] "a"
[[3]]
[[3]][[1]]
[1] "b" "c" "d"
最佳答案
更新
当差异超过1个字符时,出现了一个问题,它创建了另一行。为了克服这个问题,我们将每个元素的paste
一起编码。这也使我们免于unlist
步骤。
df$col3 <- mapply(function(x, y) paste0(setdiff(y, x), collapse = ""),
strsplit(as.character(df$y1), "\\."), strsplit(as.character(df$y2), "\\."))
原始答案
我们可以使用
mapply
并拆分“”上的两列。使用strsplit
,然后使用setdiff
区别它们之间的差异。df$col3 <- mapply(function(x, y) setdiff(y, x),
strsplit(as.character(df$y1), "\\."), strsplit(as.character(df$y2), "\\."))
df
# y1 y2 col3
#1 a.b. a.b.c. c
#2 a. a.b. b
#3 b.c.d. b.c.d.
如果我们不希望将
col3
列为列表,则可以对其进行unlist
,其中一个问题是,如果我们通过unlist
将其从中删除character(0)
值。要保留该值,我们需要对其进行其他检查。取自here。unlist(lapply(df$col3,function(x) if(identical(x,character(0))) ' ' else x))
#[1] "c" "b" " "
关于R-数据帧中2组之间的差,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49889554/