首页 > 解决方案 > 在对它们执行转换时跨列求和

问题描述

假设我有以下数据集

test_df = game_df = read.table(text = "a_bias b_bias c_bias d_bias
dog dog cat cat
NA NA NA NA
cat cat cat cat
dog NA dog dog", header = T)

我想创建一个名为的新列,它等于所有以 word 结尾的列中出现dog_sum的总次数。这是我目前的方法:dogbias

test_df %>% rowwise() %>%
  mutate(dog_sum = sum(across(ends_with("bias"), ~ifelse(. == "dog", 1, 0)), na.rm = T))

问题是当整行包含NAs. 有没有更好的方法来解决这个问题?

更一般地说,我想为匹配的每一列改变新列,ends_with("bias")如果包含,则此新列应设置为 1,dog否则设置为 0。因此,最终结果将是有四个名为a_bias_dogb_bias_dog等的列,如果该特定行存在“dog”,则设置为 1,否则设置为 0。我如何实现这一目标?

标签: rdplyr

解决方案


我们可以rowSums使用矢量化方法来做到这一点,并且应该比rowwise/sum

library(dplyr)
test_df %>% 
   mutate(dog_sum = rowSums(across(ends_with('bias')) == 'dog',
       na.rm = TRUE))

-输出

   a_bias b_bias c_bias d_bias dog_sum
1    dog    dog    cat    cat       2
2   <NA>   <NA>   <NA>   <NA>       0
3    cat    cat    cat    cat       0
4    dog   <NA>    dog    dog       3


如果我们想生成新列,请使用

test_df %>%
    mutate(across(ends_with('bias'), ~ +(. %in% 'dog'), .names = "{.col}_dog"))

-输出

   a_bias b_bias c_bias d_bias a_bias_dog b_bias_dog c_bias_dog d_bias_dog
1    dog    dog    cat    cat          1          1          0          0
2   <NA>   <NA>   <NA>   <NA>          0          0          0          0
3    cat    cat    cat    cat          0          0          0          0
4    dog   <NA>    dog    dog          1          0          1          1

推荐阅读