【问题标题】:Transforming columns based off separate dataframe - R solution基于单独的数据框转换列 - R 解决方案
【发布时间】:2021-01-23 13:29:29
【问题描述】:

我正在尝试编写一些更复杂的代码。我有一个问题,我有一个解决方案,但我想增加代码的灵活性。

输入数据(d):

ID  Height_cm   Height_m    Weight_kg   Weight_lb
1     180                        70 
2     165                                  120
3                  1.8           80 
4     100                                  60
5     190                                  200
6                  1.7           100

我想将身高转换为厘米,体重转换为公斤,所有这些都在这样的一列中:

ID  Height  Weight
1   180       70
2   165       54
3   180       80
4   100       45
5   190       90
6   170      100

我有一个解决方案,但它是硬编码的:

library(tidyverse)
d$Height <- NA
d$Weight <-NA
d$Height <- ifelse(!is.na(d$Height_cm), d$Height_cm, d$Height_m * 0.01)
d$Weight <- ifelse(!is.na(d$Weight_kg), d$Weight_kg, d$Weight_lb * 0.45)

d <- d %>% select(ID, Height, Weight)

我想要更复杂并接受一个输入文件(如下)并根据该数据框进行转换。结果将是相同的,但它使用这种转换 df 来实现相同的事情:

Transformation_d:

marker      unit        new_col_name    transformation
Height_cm   centimetre  Height          1
Height_m    metre       Height          0.01
Weight_kg   kilogram    Weight          1
Weight_lb   pounds      Weight          0.45

这就是我卡住的地方......我会很感激一些指导。

放轻松,我是 R 新手!

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    我猜Height_mtransformation 值应该是 100。

    您可以使用cur_column() 获取列名以匹配Transformation_d 数据框并获取对应的transformation 值进行相乘。

    library(dplyr)
    
    d %>%
      mutate(across(-1, ~. * Transformation_d$transformation[match(cur_column(), 
                             Transformation_d$marker)])) %>%
      transmute(ID, 
                Height = coalesce(Height_cm, Height_m), 
                Weight = coalesce(Weight_kg, Weight_lb))
    
    #  ID Height Weight
    #1  1    180     70
    #2  2    165     54
    #3  3    180     80
    #4  4    100     27
    #5  5    190     90
    #6  6    170    100
    

    base R中的类似过程

    cbind(d[1], 
          transform(sweep(d[-1], 2, 
            Transformation_d$transformation[match(names(d)[-1], 
            Transformation_d$marker)], `*`), 
            Height = ifelse(is.na(Height_cm), Height_m, Height_cm), 
            Weight = ifelse(is.na(Weight_kg), Weight_lb, Weight_kg)))
    

    【讨论】:

    • 谢谢,这真的很有帮助。是否可以将转换后的结果自动转换为 Transformation_d$new_col_name 中值的新列,而不必对列名进行硬编码?我的数据集有数百个需要转换的列,并且自动化它们进入哪个新列比单独编码每个列更可取......希望这是有道理的。
    • @lecb 此解决方案可能有助于动态执行此操作stackoverflow.com/questions/54971918/…
    猜你喜欢
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多