【问题标题】:R - Filling column of dataframe with values of other columns based on a string in another columnR - 根据另一列中的字符串用其他列的值填充数据框的列
【发布时间】:2021-10-21 14:02:24
【问题描述】:

我实际上有一个非常简单的任务要做,但我就是找不到解决方案。我有一个带有 2 列数字和 1 列 3 个不同字符串的 df。我现在想添加第 4 列 V4,我想用 V1 和 V2 的值填充,具体取决于 V3 列。

> df
   V1 V2 V3
1   1  6  P
2   2  7  P
3   3  8  N
4   4  9  B
5   5 10  P
6   6 11  B
7   7 12  N
8   8 13  N
9   9 14  P
10 10 15  P

structure(list(V1 = 1:10, V2 = 6:15, V3 = c("P", "P", "N", "B", "P", "B", "N", "N", "P", "P")), row.names = c(NA, -10L), class = "data.frame")

对于“P”,我想取 V1,对于“N”,我想取 V2,对于“B”,我理想情况下希望两个值彼此相邻(V1|V2),但不让它们成为字符,它们必须保持数字。如果这不可能,则应填写较大的数字。

我的输出应该是这样的(数字)。或者,如果无法显示 4|9 或类似数字的内容,则仅显示这 2 个中较大的数字。

   V1 V2 V3   V4
1   1  6  P    1
2   2  7  P    2
3   3  8  N    8
4   4  9  B  4|9
5   5 10  P    5
6   6 11  B 6|11
7   7 12  N   12
8   8 13  N   13
9   9 14  P    9
10 10 15  P   10

我发现了很多如何通过仅填充列来执行此操作,但我找不到任何示例根据 3 个条件用其他列的值填充列。我尝试了带有循环和子集的 if 语句,但到目前为止我失败了。

【问题讨论】:

    标签: r if-statement conditional-statements subset


    【解决方案1】:

    我们可以用case_when创造条件。

    library(dplyr)
    library(stringr)
    df %>% 
        mutate(V4 = case_when(V3 == 'B' ~ str_c(V1, V2, sep = '|'),
                              V3 == 'P' ~ as.character(V1), 
                               TRUE ~ as.character(V2)))
    

    -输出

    df
       V1 V2 V3   V4
    1   1  6  P    1
    2   2  7  P    2
    3   3  8  N    8
    4   4  9  B  4|9
    5   5 10  P    5
    6   6 11  B 6|11
    7   7 12  N   12
    8   8 13  N   13
    9   9 14  P    9
    10 10 15  P   10
    

    如果我们需要一个数字列并且“B”应该是 NA

    df %>%
        mutate(V4 = case_when(V3 == 'P' ~ V1,
                              V3 == 'N' ~ V2))
    

    -输出

       V1 V2 V3 V4
    1   1  6  P  1
    2   2  7  P  2
    3   3  8  N  8
    4   4  9  B NA
    5   5 10  P  5
    6   6 11  B NA
    7   7 12  N 12
    8   8 13  N 13
    9   9 14  P  9
    10 10 15  P 10
    

    或者,如果我们需要numeric 列和每行max,则在“B”的情况下使用pmax 返回每​​行的最大值

    df %>%
        mutate(V4 = case_when(V3 == 'P' ~ V1,
                              V3 == 'N' ~ V2, V3 == 'B' ~ pmax(V1, V2)))
    

    -输出

      V1 V2 V3 V4
    1   1  6  P  1
    2   2  7  P  2
    3   3  8  N  8
    4   4  9  B  9
    5   5 10  P  5
    6   6 11  B 11
    7   7 12  N 12
    8   8 13  N 13
    9   9 14  P  9
    10 10 15  P 10
    

    【讨论】:

    • 谢谢,这有帮助。问题只是 V4 是一个字符。有没有办法将两个值放在一个单元格中而不使它们成为数字?当我想把 V4 作为.numeric 时,4|9 和 6|11 是 Na。
    • @Mr.Spock 这是可能的。那么你只需要'P'和'N'的条件,另一个将自动NA
    • 我知道,但不幸的是我也确实需要“B”。有没有办法将两个数字都写成一个单元格中的数字?
    • @Mr.Spock 列只能有一种类型,否则您需要一个 list 列,其中“B”元素对应于两个值的向量
    • 好的,我明白了。所以在那种情况下,如果是“B”,我只会填写更高的数字(绝对值)。
    猜你喜欢
    • 1970-01-01
    • 2019-06-06
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多