【问题标题】:Mutate with condition on ALL other columns to add a new column在所有其他列上使用条件进行变异以添加新列
【发布时间】:2021-01-26 10:06:58
【问题描述】:

我的第一个问题!希望我说得清楚简单:D

主题

如果基于所有其他列内容的条件,我想添加一个新列。

数据和想要的转换

我有以下(有点乱)数据框,我正在尝试添加一列,如果另一列包含 0,则该列应包含“是”,如果其他列均不包含“0”,则应包含“否”。

library(tidyverse)
library(readxl)
all_extract <- read_excel("all_extract.xlsx")
View(all_extract)                                                                                                                                 
all_extract
A tibble: 25 x 14
     tag1 `tag1 -1`  tag2 `tag2 -1`  tag3 `tag3 -1`  tag4 `tag4 -1`  tag5 `tag5 -1`  tag6 `tag6 -1`  tag7 `tag7-1`
     <dbl> <lgl>     <dbl> <lgl>     <dbl> <lgl>     <dbl> <dbl>     <dbl> <dbl>     <dbl> <lgl>     <dbl>  <dbl>
1     2    NA        0     NA        1     NA        2     NA         1    -1        1     NA         1     0
2     2    NA        2     NA        1     NA        2     NA         2    NA        1     NA         2     0
3     1    NA        1     NA        1     NA        2     NA         1    NA        2     NA         1     0
4     1    NA        2     NA        1     NA        2     NA         1    NA        1     NA         1     0
5     2    NA        1     NA        1     NA        2     NA         1    NA        2     NA         1     0
6     2    NA        1     NA        1     NA        2     NA         0    NA        1     NA         2     0
7     1    NA        2     NA        1     NA        2     NA         0    NA        1     NA         1     0
8     1    NA        1     NA        2     NA        2     NA         1    NA        1     NA         1     0
9     1    NA        2     NA        1     NA        2     NA         1    NA        2     NA         1     0
10    1    NA        2     NA        1     NA        2     -1         1    NA        2     NA         1     0
# … with 15 more rows

对于复制,可以下载文件with this link

尝试和问题

我已尝试使用dplyr mutate 来实现,但它适用于一个或多个命名 列,而不适用于所有列;我需要编写一个脚本,我可以将其应用于一堆列数不同的文件。如果我的理解是正确的,mutate_allmutate_if 不会做我想做的事,因为与mutate 不同,它们不会添加新列,而是更改与条件匹配的现有列的​​内容。然而,它们是我在互联网上寻求帮助时唯一能找到的东西。

例如,我可以在 one 列上应用 mutate 条件:

all <- all_extract %>%
    mutate(Final_schwa = case_when(syll_tag2==0 ~ 'Schwa',
        TRUE ~ 'No schwa'))

我为 multiple 列找到了很多解决方案,all 列没有找到解决方案。

我也尝试在mutate 中使用across,但我不知道如何指示所有列。理想情况下,我认为我可以使用类似的东西:

mutate(across(starts_with("tag"), "Yes"))

但我无法获得正确的语法以使其正常工作。另外,我什至不确定across 是否应该能够做我想做的事。

总结

所以:有没有办法应用 real mutate(用于添加列)与基于所有其他列的条件(新列填充“是/否”内容基于全列条件)?

如果您能提供帮助,请提前致谢!

【问题讨论】:

    标签: r dataframe dplyr


    【解决方案1】:

    使用pivot_longer

    正如 Konrad 所指出的,此解决方案优于以下解决方案,因为它保留了数据类型 - 如果您的数据包含多种类型,它们将被 t 强制转换为单一类型,这可能导致数据丢失。

    new_col <- 
    all_extract %>%
    pivot_longer(everything()) %>% #This will make a 2-col df w/ names: (name, value)
    group_by(name) %>% 
    summarise(any_zero = any(value == 0))
    
    rbind(all_extract, new_col["any_zero"])
    

    或者转置数据和summarise(across(everything))

    如果你是一个视觉思维者,我认为这个解决方案会更直观一点,但存在数据丢失的风险,因为t 返回一个矩阵,而矩阵不能包含多种类型。

    new_col <- 
    all_extract %>%
    t %>%
    as_tibble %>% # (because t() returns a matrix)
    summarise(across(everything(), function(x){
    any(x == 0) 
    })) %>%
    t # transposing again will coerce our single row df into a column vector
    
    all_extract$new_col <- new_col
    

    【讨论】:

    • 我会使用pivot_longer 而不是t(矩阵函数)。它保留了正确的数据类型。 — 而x %in% 0 更传统地写作x == 0
    【解决方案2】:

    如果连续至少有 1 个零,您要添加“是”吗?

    您可以将rowSums 用作:

    all_extract$new_col <- ifelse(rowSums(all_extract == 0, na.rm = TRUE) > 0, 'yes', 'no')
    
    #Without ifelse
    all_extract$new_col <- c('No', 'Yes')[(rowSums(all_extract == 0, na.rm = TRUE) > 0) + 1]
    

    【讨论】:

    • 工作得很好,对于像我这样的菜鸟来说,语法简单易懂!非常感谢罗纳克!
    猜你喜欢
    • 2022-07-20
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多