【问题标题】:Conditionally replacing a substring value in a column with substrings of other columns有条件地用其他列的子字符串替换列中的子字符串值
【发布时间】:2018-06-20 16:53:38
【问题描述】:

假设您有以下简单的数据框:

Input <- c("X0_1-2 + X1_1-2","X0_1-2 + X1_1-2","X0_1-3 + X1_1-3","X0_3-2 + X1_3-2","X0_3-1 + X1_3-1","X0_2-1 + X1_2-1","X0_2-3 + X1_2-3","X0_13-1 + X1_13-1")
State1 <- c("1-3","1-3","1-2","3-1","3-2","2-1","2-1","13-3")
State2 <- c("1-2","1-2","1-3","3-2","3-1","2-3","2-3","13-1")
DataFrame <- cbind(Input,State1,State2)
DataFrame <- as.data.frame(DataFrame)

产量

            Input State1 State2
1 X0_1-2 + X1_1-2    1-3    1-2
2 X0_1-2 + X1_1-2    1-3    1-2
3 X0_1-3 + X1_1-3    1-2    1-3
4 X0_3-2 + X1_3-2    3-1    3-2
5 X0_3-1 + X1_3-1    3-2    3-1
6 X0_2-1 + X1_2-1    2-1    2-3
7 X0_2-3 + X1_2-3    2-1    2-3
8 X0_13-1 + X1_13-1  13-3   13-1

我试图想出一种聪明的方法来添加一个与“输入”列相等的额外列,但要使“_”后面的值 是 State1 或 State2 的那些,根据它与 Input 中相应的子字符串不同,即在这种情况下,期望的结果是

            Input State1 State2          Outcome
1 X0_1-2 + X1_1-2    1-3    1-2 X0_1-3 + X1_1-3
2 X0_1-2 + X1_1-2    1-3    1-2 X0_1-3 + X1_1-3
3 X0_1-3 + X1_1-3    1-2    1-3 X0_1-2 + X1_1-2
4 X0_3-2 + X1_3-2    3-1    3-2 X0_3-1 + X1_3-1
5 X0_3-1 + X1_3-1    3-2    3-1 X0_3-2 + X1_3-2
6 X0_2-1 + X1_2-1    2-1    2-3 X0_2-3 + X1_2-3
7 X0_2-3 + X1_2-3    2-1    2-3 X0_2-1 + X1_2-1
8 X0_13-1 + X1_13-1  13-3    13-1 X0_13-3 + X1_13-3

但到目前为止一直没有成功。

这个想法是用 State1 或 State2 的值替换输入字段中 _ 之后的任何内容,在总和的两侧,以不同者为准。

任何想法/意见将不胜感激。 谢谢!

【问题讨论】:

    标签: r dataframe replace substring


    【解决方案1】:

    如果我理解正确,Input 和 Outcome 表示的状态对于字符串的 "XO" 和 "X1" 部分是相同的。 State1 和 State2 也永远不会相同。在这种情况下,您可以从输入中提取状态,将其与两种状态之一进行比较,然后将输出字符串粘贴在一起:

    output <- ifelse(substring(DataFrame$Input, 13) == State1, State2, State1)
    DataFrame$Outcome <- paste("X0_", output, " + X1_", output, sep = "")
    DataFrame
    #               Input State1 State2           Outcome
    # 1   X0_1-2 + X1_1-2    1-3    1-2   X0_1-3 + X1_1-3
    # 2   X0_1-2 + X1_1-2    1-3    1-2   X0_1-3 + X1_1-3
    # 3   X0_1-3 + X1_1-3    1-2    1-3   X0_1-2 + X1_1-2
    # 4   X0_3-2 + X1_3-2    3-1    3-2   X0_3-1 + X1_3-1
    # 5   X0_3-1 + X1_3-1    3-2    3-1   X0_3-2 + X1_3-2
    # 6   X0_2-1 + X1_2-1    2-1    2-3   X0_2-3 + X1_2-3
    # 7   X0_2-3 + X1_2-3    2-1    2-3   X0_2-1 + X1_2-1
    # 8 X0_13-1 + X1_13-1   13-3   13-1 X0_13-3 + X1_13-3
    

    此解决方案适用于任何长度的“状态”子字符串(例如,"1-1" and "201-14") expressed by theInput` 变量。您可以使用正则表达式,但在这种情况下,基于位置进行提取有效(并且更有效)。

    【讨论】:

    • 看起来 gr8,谢谢!不想咄咄逼人,你能想出一种让子字符串处理更大参数的方法吗?以防万一可能需要 X13_13-1 或其他格式的“输入”,而不必逐个案例...
    • @Arrebimbomalho 我不确定我是否理解新问题。也许把它写成一个新问题,并附上你正在寻找的行为的例子,我们会看看我是否能回答。
    • 因此,有条件地替换“输入”中 _ 之后的所有内容而不考虑长度的方法会很好......
    • @Arrebimbomalho 好的,它现在适用于任何长度的状态子字符串。因为substring(相对于它的合作伙伴substr)在没有给出last 参数时一直提取到text 参数的末尾,所以我们只是从末尾拉出。我还通过将substring 的text 参数更改为DataFrame$Input 而不仅仅是Input,从而修复了原始代码中的一个潜在问题。这样,如果您对数据框进行任何操作(或者如果您没有按照您在问题中向我们展示的方式生成它),您就是从数据框而不是初始变量中提取它。
    • Gr8,谢谢!无论如何,我编辑了原始问题,以防其他人有足够的勇气插话:)
    【解决方案2】:

    我会这样做,假设 df 是您的数据框:

    replacement <- c("State2","State1")[mapply(grepl, df$State2, df$Input)+1]
    df$output <- sapply(1:nrow(df), function(i)gsub( "\\d+-\\d+",df[i, replacement[i]],df[i,"Input"]))
    

    输出:

    > df
                Input State1 State2          output
    1 X0_1-2 + X1_1-2    1-3    1-2 X0_1-3 + X1_1-3
    2 X0_1-2 + X1_1-2    1-3    1-2 X0_1-3 + X1_1-3
    3 X0_1-3 + X1_1-3    1-2    1-3 X0_1-2 + X1_1-2
    4 X0_3-2 + X1_3-2    3-1    3-2 X0_3-1 + X1_3-1
    5 X0_3-1 + X1_3-1    3-2    3-1 X0_3-2 + X1_3-2
    6 X0_2-1 + X1_2-1    2-1    2-3 X0_2-3 + X1_2-3
    7 X0_2-3 + X1_2-3    2-1    2-3 X0_2-1 + X1_2-1
    8 X0_2-1 + X1_2-1    2-3    2-1 X0_2-3 + X1_2-3
    

    【讨论】:

    • 太棒了!非常感谢
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2019-11-21
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    相关资源
    最近更新 更多