首页 > 解决方案 > 使用存储在不同数据框中的值来改变数据框的列

问题描述

我创建了两个数据框,其中df.1包含我的主要数据。

ID  A_ratio   B_ratio  C_ratio
1    0.9       7.6      3.5
2    3.1       4.4      0.7     
3    6.3       8.2      1.2

数据框cut仅包含一行。

A_cut  B_cut  C_cut
 4.5    5.3    2.0

我现在想使用存储的值进行二值cut化,df转向X_ratio <= X_cut和。可以调用新列。我尝试了以下方法:1X_ratio > X_cut0X_bindplyr

df.2 <- df.1 %>%
  mutate(across(ends_with("ratio"), ~if_else(. <= get(cut[str_replace(cur_column(),"ratio","cut")]), 1, 0)
            .names = "{.col}_bin"))%>%
  rename_with(~str_replace(.,"_ratio",""),contains("_ratio_"))
  select(ID, ends_with("bin"))

但不幸的是,我得到了一个Error: unexpected symbol. 有人能指出我的错误吗?所需的输出df.2将是

ID A_bin B_bin C_bin
1   1     0     0
2   1     1     1
3   0     0     1

提前非常感谢!

标签: rdplyr

解决方案


之前有一个,缺失.names,如果我们从 中提取列cut,我们不需要任何get内容​​,除了mutate, 用于transmute仅返回那些需要的列,以便select可以删除最后一步

library(dplyr)
library(stringr)
df.1 %>%
  transmute(ID, across(ends_with("ratio"), 
      ~if_else(. <=  cut[[str_replace(cur_column(),"ratio","cut")]], 
            1, 0),
        .names = "{.col}_bin")) %>% 
   rename_with(~str_replace(.,"_ratio",""),contains("_ratio_"))

-输出

#  ID A_bin B_bin C_bin
#1  1     1     0     0
#2  2     1     1     1
#3  3     0     0     1

当我们返回二进制列时,if_else并不是真正需要的。逻辑向量可以强制为二进制as.integer或包装+(

df.1 %>%
  transmute(ID, across(ends_with("ratio"), 
      ~as.integer(. <=  cut[[str_replace(cur_column(),"ratio","cut")]]),
        .names = "{.col}_bin")) %>% 
   rename_with(~str_replace(.,"_ratio",""),contains("_ratio_"))

注意:cut是函数名,所以最好不要用函数名来命名对象

数据

df.1 <- structure(list(ID = 1:3, A_ratio = c(0.9, 3.1, 6.3), B_ratio = c(7.6, 
4.4, 8.2), C_ratio = c(3.5, 0.7, 1.2)), class = "data.frame", row.names = c(NA, 
-3L))

cut <- structure(list(A_cut = 4.5, B_cut = 5.3, C_cut = 2), class = "data.frame",
row.names = c(NA, 
-1L))

推荐阅读