用于检查值并根据结果添加值的功能 示例数据框:更长的枢轴点使用case_when 枢轴更宽功能解决方案示例

如何解决用于检查值并根据结果添加值的功能 示例数据框:更长的枢轴点使用case_when 枢轴更宽功能解决方案示例

有! 我有一张桌子:

532 obs. of  44 variables

它看起来像这样:

A tibble: 10 x 44
       ID   PVD Vasculitis   CVA   CHF    MI   HTN  COPD
           <dbl> <dbl>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
     1 11    NA         NA    NA    NA    NA     1    NA
     2 22     1         NA     1    NA     1     1     1
     3 33    NA         NA    NA    NA     1     1     1
     4 44    NA         NA     1    NA    NA    NA     1
     5 55     1         NA    NA     1     1     1     1
     6 66    NA         NA    NA     1     1     1     1
     7 77    NA         NA    NA    NA    NA    NA    NA
     8 88    1         NA     1     1     1     1     1
     9 99    NA         NA    NA    NA    NA     1     1
    10 1010    NA         NA    NA     1     1     1    NA
    # ... with 36 more variables: TB <dbl>,Diabetes <dbl>,#   Liver <dbl>,CRF <dbl>,Dementia <dbl>,Obesity <dbl>,#   Hearing_loss <dbl>,Paraplegia <dbl>,`Peptic
    #   _ulcer` <dbl>,Autoimmune <dbl>,Breast_Cancer <dbl>,#   Colon_Cancer <dbl>,Anus_Cancer <dbl>,#   Stomach_Cancer <dbl>,Pancreas_Cancer <dbl>,#   Ovarian_Cancer <dbl>,Cervix_uteri_Cancer <dbl>,#   Uterus_Cancer <dbl>,Prostate_Cancer <dbl>,#   Melanoma <dbl>,Lymphoma <dbl>,Leukemia <dbl>,#   Thyroid_Cancer <dbl>,Head_and_neck_Cancer <dbl>,#   Kidney_Cancer <dbl>,Adrenal_Cancer <dbl>,#   Bone_Cancer <dbl>,Testicular_Cancer <dbl>,#   Skin_Cancer <dbl>,Urinary_Cancer <dbl>,#   Liver_Cancer <dbl>,Musculoskeletal_Cancer <dbl>,#   Multiple_myeloma <dbl>,CNS_Cancer <dbl>,#   Unknown_primary_Cancer <dbl>,solid <dbl>

因此,第一列是唯一的ID,后续列是不同疾病的名称(无重复)。第1行中的值分别是如果有疾病和没有NA。 例如,患者编号55(第5行)具有“ PVD”,“ CHF”,“ MI”,“ HTN”,“ COPD”等。 我还创建了一个带有癌症名称的载体(这些是第19至43列的名称)。 我想编写一个函数来检查此表,并且如果列名与我的载体的癌症名称匹配,它将检查该行(患者数)在匹配的列中是否患有癌症(如果有标记1 ),则将标记添加到名称为“ solid”的最后一列。至少一个巧合就足够了。因此,对于所有患者。 例如,如果同一位患者55患有“结肠癌”(第20列),则应在“实心”列中加1,如果他患有其他癌症也没关系。 我尝试了类似的方法,但是没有成功,并且被卡住了:

solid_tumor <- function(x){
    x <- as.data.frame(x)
    for (i in length(x)) {
        if (colnames(x) %in% tumors) {
            if(any(x==1)) {
               x[i] <- 1 
            }
        }
    }
}

谢谢。

解决方法

一种使用tidyverse

的关键方法

在我看来,最好是轮换数据,以便更轻松地编写函数。

示例数据框:

首先,我们制作一个示例数据框,以便其他人更轻松地考虑这个问题和将来的解决方案:

library(tidyverse)
df <- tibble(
  ID     = sample(10:100,30),car    = sample(na_or_1,30,replace = T,prob = c(.05,.95)),bug    = sample(na_or_1,blast  = sample(na_or_1,opt    = sample(na_or_1,star   = sample(na_or_1,queue  = sample(na_or_1,man    = sample(na_or_1,ring   = sample(na_or_1,happy  = sample(na_or_1,after  = sample(na_or_1,hug    = sample(na_or_1,dragon = sample(na_or_1,.95))
)

更长的枢轴点

现在,我们可以使用pivot_longer函数对ID列进行更长的数据透视。

df %>% 
  pivot_longer(cols = -ID) %>% 
  filter(!is.na(value))

这将产生以下输出: ID Name value其中name ==列名(癌症名称)和value == 1(所有NA均被过滤掉)

这使函数更容易将逻辑应用于您要执行的操作。

使用case_when

进行更改

使用tumors的向量,我可以应用case_when逻辑,并mutate新建一个列solid。我拿出了NA过滤器,因为我想到您会希望DF基本上保持不变。

df %>% 
    pivot_longer(cols = -ID) %>% 
    # filter( !is.na(value) ) %>% 
    mutate(solid = case_when(name %in% tumors &
                           !is.na(value) ~ 1,T ~ NA_real_))

枢轴更宽

最后,我将使用pivot_wider撤消更长的数据透视。我将从更长的时间内使用原来创建的名称列中获取名称。

 df %>% 
pivot_longer(cols = -ID) %>% 
# filter( !is.na(value) ) %>% 
mutate(solid = case_when(name %in% tumors &
                           !is.na(value) ~ 1,T ~ NA_real_)) %>% 
pivot_wider(
  names_from = name
)

功能解决方案

myfunction <- function(df,tumors){
 df %>% 
  pivot_longer(cols = -ID) %>% 
  # filter( !is.na(value) ) %>% 
  mutate(solid = case_when(name %in% tumors &
                           !is.na(value) ~ 1,T ~ NA_real_)) %>% 
  pivot_wider(
    names_from = name
  )
}

示例

现在,当我获取肿瘤的载体时,我可以将其放入函数和df中,并附上您原始问题的答案。

tumors <- c("hug","happy","man")
myfunction(df,tumors)


# # A tibble: 32 x 14
#      ID solid car   bug   blast opt   star  queue man   ring  happy after hug   dragon
#     <int> <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> 
# 1    16    NA NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    
# 2    98    NA NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    
# 3    74    NA NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    
# 4    50    NA NA    NA    NA    NA    NA    1     NA    NA    NA    NA    NA    NA    
# 5    50     1 NA    NA    NA    NA    NA    NA    1     NA    NA    NA    NA    NA    
# 6    29    NA NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    
# 7    94    NA NA    NA    NA    1     NA    NA    NA    NA    NA    NA    NA    NA    
# 8    19    NA NA    1     NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    
# 9    46    NA NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    
# 10   15    NA NA    1     NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  
,

以其他方式看待这个问题。

简单功能

这证明了简单的功能方法的简单性和灵活性:

func <- function(x,candidates) {
  cnames <- intersect(candidates,colnames(x))
  if (length(cnames)) {
    +(rowSums(!is.na(subset(x,select = cnames))) > 0)
  } else rep(0L,nrow(x))
}

dat$solid <- func(dat,c("CHF","MI"))
dat
#      ID PVD Vasculitis CVA CHF MI HTN COPD solid
# 1    11  NA         NA  NA  NA NA   1   NA     0
# 2    22   1         NA   1  NA  1   1    1     1
# 3    33  NA         NA  NA  NA  1   1    1     1
# 4    44  NA         NA   1  NA NA  NA    1     0
# 5    55   1         NA  NA   1  1   1    1     1
# 6    66  NA         NA  NA   1  1   1    1     1
# 7    77  NA         NA  NA  NA NA  NA   NA     0
# 8    88   1         NA   1   1  1   1    1     1
# 9    99  NA         NA  NA  NA NA   1    1     0
# 10 1010  NA         NA  NA   1  1   1   NA     1

整洁

不幸的是,dplyr并不容易将所有列传递给mutate中的函数。 (我敢肯定有人会推荐c_across()……我还没有发现它在这种情况下的用法很优雅。)

第一个刺可能会使用点.

dat %>%
  mutate(solid = func(.,"MI")))

它在没有任何分组的情况下仍然可以正常工作,但是无论使用哪种分组,它始终使用整个框架,因此,如果考虑到这一点,则会出现错误:

dat %>%
  group_by(ID) %>%
  # I know this is equivalent to rowwise() with this data
  mutate(solid = func(.,"MI")))
# Error: Problem with `mutate()` input `solid`.
# x Input `solid` can't be recycled to size 1.
# i Input `solid` is `func(.,"MI"))`.
# i Input `solid` must be size 1,not 10.
# i The error occured in group 1: ID = 11.

所以简单的解决方法是do

dat %>%
  group_by(ID) %>%
  do(mutate(.,solid = func(.,"MI"))))

(我意识到分组与 this 数据无关,但是将“简单”非tidyverse函数应用于当前框架的所有列可能在其他地方有用,并且尊重分组很重要。 )

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-