当前位置: 首页 > 知识库问答 >
问题:

基于多个列值创建具有连续序列和rep的新列

锺离鸿
2023-03-14

谈到R编码,我目前有点墨守成规。我一直在尝试使用mutate、seq和rep函数来生成一个新列,该列迭代多个列值和不同的条件,但结果并不正确。下面是我的一些数据片段:

library(tidyverse)
library(data.table)
library(stringr)

lipidData <- data.frame("Type"=c(rep("LDL",5),rep("HDL",5)),
                        "featureID"=c(12,12,12,12,13,13,14,15,16,17),
                        "featureID2"=c(21,22,23,26,31,31,31,31,38,40))
lipidWrong <- lipidData %>%
group_by(Type,featureID) %>% 
group_by(Type,featureID2) %>% 
mutate(lipidName=paste0(rep("lipid",n()),"_",seq(1,n())))
lipidWrong
  Type  featureID featureID2 lipidName
   <fct>     <dbl>      <dbl> <chr>    
 1 LDL          12         21 lipid_1  
 2 LDL          12         22 lipid_1  
 3 LDL          12         23 lipid_1  
 4 LDL          12         26 lipid_1  
 5 LDL          13         31 lipid_1  
 6 HDL          13         31 lipid_1  
 7 HDL          14         31 lipid_2  
 8 HDL          15         31 lipid_3  
 9 HDL          16         38 lipid_1  
10 HDL          17         40 lipid_1 

我希望按类型和特征 ID 对 lipidName 进行分组,然后查看类型特征 ID2,而不是不正确的数据表。如果它们具有相同的类型和特征 ID,则将它们计为脂质名称的相同脂质。如果它们具有相同的类型和特征ID2,则将它们计为脂质名称的相同脂质。由于我的真实数据集包括

我希望看到我的结果为:

lipidCorrect
   Type featureID featureID2 lipidName
1   LDL        12         21   lipid_1 # same type and featureID
2   LDL        12         22   lipid_1 # same type and featureID
3   LDL        12         23   lipid_1 # same type and featureID
4   LDL        12         26   lipid_1 # same type and featureID
5   LDL        13         31   lipid_2 # although featureID is the same with row6, it has a different type
6   HDL        13         31   lipid_3 # same type and featureID2
7   HDL        14         31   lipid_3 # same type and featureID2
8   HDL        15         31   lipid_3 # same type and featureID2
9   HDL        16         38   lipid_4 
10  HDL        17         40   lipid_5

如果我的group_by()和突变()有什么问题,请告诉我,也请让我知道产生预期结果的更好方法。

谢谢!

共有2个答案

沈栋
2023-03-14

下面是一个版本,使用助手变量来跟踪哪个分组生成唯一ID,然后将其转换为最终变量:

lipidData %>%
  group_by(Type, featureID) %>% 
  mutate(
    name_id = case_when(n() > 1 ~ paste("fid1", cur_group_id()), TRUE ~ NA_character_)
  ) %>%
  group_by(Type,featureID2) %>% 
  mutate(
    name_id = case_when(is.na(name_id) ~ paste("fid2", cur_group_id()), TRUE ~ name_id)
  ) %>%
  ungroup() %>%
  mutate(
    lipidName = paste("lipid", as.integer(factor(name_id, levels = unique(name_id))), sep = "_")
  ) %>%
  select(-name_id)
# # A tibble: 10 x 4
#    Type  featureID featureID2 lipidName
#    <chr>     <dbl>      <dbl> <chr>    
#  1 LDL          12         21 lipid_1  
#  2 LDL          12         22 lipid_1  
#  3 LDL          12         23 lipid_1  
#  4 LDL          12         26 lipid_1  
#  5 LDL          13         31 lipid_2  
#  6 HDL          13         31 lipid_3  
#  7 HDL          14         31 lipid_3  
#  8 HDL          15         31 lipid_3  
#  9 HDL          16         38 lipid_4  
# 10 HDL          17         40 lipid_5  
颛孙英勋
2023-03-14

如果我正确理解了这个问题(使用了@Gregor Thomas的澄清性问题和评论),基于tidyverse的(笨拙的)解决方案可能如下所示。

library(dplyr)
library(stringr)

lipidData %>%
  group_by(Type, featureID) %>%
  mutate(lipidGroup1 = +(n() > 1)) %>%
  group_by(Type, featureID2) %>%
  mutate(lipidGroup2 = +(n() > 1)) %>%
  ungroup() %>%
  mutate(lipidGroup3 = +(lipidGroup1 == 0 & lipidGroup2 == 0)) %>%
  group_by(Type, featureID) %>%
  mutate(lipidGroup1 = if_else(n() > 1 & row_number() == min(row.names(.)), 1, 0)) %>%
  group_by(Type, featureID2) %>%
  mutate(lipidGroup2 = if_else(n() > 1 & row_number() == min(row.names(.)), 1, 0)) %>%
  ungroup() %>%
  mutate(lipidName = str_c('lipid_', cumsum(lipidGroup1 + lipidGroup2 + lipidGroup3))) %>%
  select(-starts_with('lipidGroup'))

#    Type  featureID featureID2 lipidName
#    <chr>     <dbl>      <dbl> <chr>    
#  1 LDL          12         21 lipid_1  
#  2 LDL          12         22 lipid_1  
#  3 LDL          12         23 lipid_1  
#  4 LDL          12         26 lipid_1  
#  5 LDL          13         31 lipid_2  
#  6 HDL          13         31 lipid_3  
#  7 HDL          14         31 lipid_3  
#  8 HDL          15         31 lipid_3  
#  9 HDL          16         38 lipid_4  
# 10 HDL          17         40 lipid_5 

 类似资料:
  • 基于dataframe列val_1值,查看其他列col_0-10标签前缀,然后创建另一列Mycl。 数据帧看起来像: 应用逻辑后所需的数据帧: 我是trid,但这不起作用:df['mycol']=df['col'df['val_1']。aType(str)] DDL生成DataFrame: 谢谢!

  • 我想将我的自定义函数(它使用if-else梯形)应用到数据帧每行中的这六列(,,,,,)。 我已经尝试了不同的方法从其他问题,但似乎仍然不能找到正确的答案,我的问题。关键的一点是,如果这个人被算作西班牙裔,他们就不能算作其他任何东西。即使他们在另一个种族栏中有一个“1”,他们仍然被算作西班牙裔,而不是两个或两个以上的种族。类似地,如果所有ERI列的总和大于1,则被计为两个或两个以上的种族,不能被计

  • 我有数据。下面的框架。我想添加一列“g”,它根据列中的连续序列对数据进行分类。也就是说,如最后一列“g”所示,h_no

  • 问题内容: 我正在尝试创建一个列(“ consec”),该列将连续计数另一个(“二进制”)中的连续值,而不使用循环。这是预期的结果: 但是这个 导致… 我看到了其他使用分组或排序的帖子,但不幸的是,我看不到如何对我有用。在此先感谢您的帮助。 问题答案: 您可以使用compare-cumsum-groupby模式(我 确实 需要解决这个问题才能编写文档),最后是: 之所以有效,是因为首先我们得到了要

  • 我有一个类似下面的数据帧,其中所有ID都是唯一的,列a、B和C的值都在0和1之间。 我想只保留A、B和C的前n个值,这样对于n=2,数据帧看起来如下: 做df.set_index('ID')['A']. n最大(2).reset_index()给我: 有没有比三次合并数据集更简单的方法?

  • 给定一个有N个元素的数组A,我想在A的所有可能的连续子序列中找到最小元素的总和。我知道如果N很小,我们可以寻找所有可能的子序列,但是当N高达10^5时,找到这个总和的最佳方法是什么? 示例:设 N=3 且 A[1,2,3] 则 ans 为 10,作为可能的连续子序列 {(1),(2),(3),(1,2),(1,2,3),(2,3)} 因此最小元素之和 = 1 2 3 1 1 2 = 10