谈到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()和突变()有什么问题,请告诉我,也请让我知道产生预期结果的更好方法。
谢谢!
下面是一个版本,使用助手变量来跟踪哪个分组生成唯一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
如果我正确理解了这个问题(使用了@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