jal*_*pic 4 r strsplit dataframe combn
这是这个问题的后续内容: Duplicating Observations of a dataframe, but also Replace Specific Variable Values in R
我尝试尽可能简洁地写,同时提供所有必要的信息。在当前示例中,我有一个如下所示的 df:
df<-data.frame(alpha=c(1, "3, 4", "2, 4, 5", 2, 1, 3, "1, 2", "1, 2, 3"),
beta=c("2, 4", "3, 4", 1, 3, 3, "1, 4", "1, 2", "1, 2, 3"),
color=c("red", "yellow"))
# alpha beta color
#1 1 2, 4 red
#2 3, 4 3, 4 yellow
#3 2, 4, 5 1 red
#4 2 3 yellow
#5 1 3 red
#6 3 1, 4 yellow
#7 1, 2 1, 2 red
#8 1, 2, 3 1, 2, 3 yellow
Run Code Online (Sandbox Code Playgroud)
所需输出
我希望它最终看起来像这样(行的顺序对我来说并不那么重要):
# alpha beta color value
#1 1 2 red 1
#2 1 4 red 1
#3 3 4 yellow 0.5
#4 2 1 red 1
#5 4 1 red 1
#6 5 1 red 1
#7 2 3 yellow 1
#8 1 3 red 1
#9 3 1 yellow 1
#10 3 4 yellow 1
#11 1 2 red 0.5
#12 1 2 yellow 0.5
#13 1 3 yellow 0.5
#14 2 3 yellow 0.5
Run Code Online (Sandbox Code Playgroud)
每当观察到具有多个不重叠/不匹配条目的 alpha 或 beta 时,该观察就会扩展。例如,原始 df 的第 1 行有 alpha="1" 和 beta="2, 4"。它们在输出中成为两个单独的行,其中 beta 的“2”和“4”分开。每次观察都会保留变量“颜色”中保存的信息。此外,新变量“值”的值为 1。
这个问题和上一个问题之间的主要区别是存在 alpha==beta 的行。
在这里,我只想保留 alpha 和 beta 的独特组合,而不是重复的。例如,原始 df 的第 8 行具有 alpha="1, 2, 3" 和 beta="1, 2, 3"。我想要单独的行,其中“alpha = 1,beta = 2”,“alpha = 1,beta = 3”,“alpha = 2,beta = 3”。同样,“颜色”变量将被复制。然而,在这里,值需要是“0.5”。
我尝试过的:
我不知道如何一次性完成这一切,所以我首先根据 alpha 是否等于 beta 来对 df 进行子集化。
x <- df[df$alpha!=df$beta,]
df$alpha<-as.character(df$alpha)
df$beta<-as.character(df$beta)
fun1 <- function(df){
df$alpha<-as.character(df$alpha)
df$beta<-as.character(df$beta)
do.call(rbind, with(df, Map(expand.grid,
alpha = strsplit(alpha, ", "),
beta = strsplit(beta, ", "),
color = color,
value = 1
)))
}
fun1(x)
Run Code Online (Sandbox Code Playgroud)
这使:
alpha beta color value
#1 1 2 red 1
#2 1 4 red 1
#3 2 1 red 1
#4 4 1 red 1
#5 5 1 red 1
#6 2 3 yellow 1
#7 1 3 red 1
#8 3 1 yellow 1
#9 3 4 yellow 1
Run Code Online (Sandbox Code Playgroud)
然后观察 alpha==beta ,这就是我陷入困境的地方......
x2 <- df[df$alpha==df$beta,]
x2
# alpha beta color
#2 3, 4 3, 4 yellow
#7 1, 2 1, 2 red
#8 1, 2, 3 1, 2, 3 yellow
Run Code Online (Sandbox Code Playgroud)
我的想法是使用分割数据strsplit
,然后使用它combn
来查找我正在寻找的组合并将其重新绑定在一起。但是,如果我想复制其他变量,这将不会像这样工作......
a<-strsplit(x2$alpha, ", ")
a.combs <- lapply(a, function(x) c(combn(x, 2, simplify=FALSE)))
matrix(unlist(a.combs),ncol=2, byrow=T)
Run Code Online (Sandbox Code Playgroud)
给出:
# [,1] [,2]
#[1,] "3" "4"
#[2,] "1" "2"
#[3,] "1" "2"
#[4,] "1" "3"
#[5,] "2" "3"
Run Code Online (Sandbox Code Playgroud)
任何关于如何获得这些组合以及预先存在的“颜色”变量以及添加新的“值”变量的想法都将受到高度赞赏。
我刚刚快速完成了此操作,所以我不确定它是否涵盖了您的所有条件,但这似乎有效。
它从几乎相同的点开始,使用我的cSplit
函数,嵌套两次,如下所示(但这一次,添加一个 ID):
library(devtools)
source_gist(11380733)
temp <- cSplit(cSplit(cbind(id = 1:nrow(df), df),
"alpha", ",", "long"),
"beta", ",", "long")
Run Code Online (Sandbox Code Playgroud)
这是新内容:
SD <- c("alpha", "beta")
## Convert "alpha" and "beta" to numeric
temp[, (SD) := lapply(.SD, as.numeric), .SDcols = SD]
## Sort your alphas and betas, and check for duplicates
## and any points where alpha equals beta
temp[, toDrop := duplicated(
paste(pmin(alpha, beta), pmax(alpha, beta))) |
alpha == beta, by = id]
## Create your "value" column
temp[, value := ifelse(any(toDrop), 0.5, 1), by = id]
## Subset and drop the irrelevant columns
out <- temp[!temp[, toDrop, with = TRUE]][, toDrop := NULL]
Run Code Online (Sandbox Code Playgroud)
这是输出:
out
# id alpha beta color value
# 1: 1 1 2 red 1.0
# 2: 1 1 4 red 1.0
# 3: 2 3 4 yellow 0.5
# 4: 3 2 1 red 1.0
# 5: 3 4 1 red 1.0
# 6: 3 5 1 red 1.0
# 7: 4 2 3 yellow 1.0
# 8: 5 1 3 red 1.0
# 9: 6 3 1 yellow 1.0
# 10: 6 3 4 yellow 1.0
# 11: 7 1 2 red 0.5
# 12: 8 1 2 yellow 0.5
# 13: 8 1 3 yellow 0.5
# 14: 8 2 3 yellow 0.5
Run Code Online (Sandbox Code Playgroud)