子集对应于数据框中另一列的两列的所有值
Subset all values from two columns that correspond to another column(s) in a dataframe
我有一个包含 4 列的数据框
ID1
ID2
Value1
Value2
1
2
zinc
sulfur
1
2
zinc
calcium
1
2
calcium
NA
3
4
carbon
iron
3
4
iron
iron
3
4
iron
carbon
前两列始终对应,因此在配置时我基本上只需要使用其中一个 ID 列。
对于每对 ID,我希望每个值都对应于其中一个 ID,并且只出现一次。
所以对于上面的例子我想要:
ID1
ID2
Values
1
2
zinc, sulfur, calcium
3
4
carbon, iron
但是,如果列表仅列出每个 ID 的每个值(唯一出现)的次数,它也可能有效。
我最终想要的是每个Value在数据集中出现的次数
例如:
Value
Count
calcium
1
carbon
1
zinc
1
iron
1
sulfur
1
我想列表可能是到达此端点的更好方法,但我更精通数据框。目前,我最感兴趣的是第一部分(获取 ID 对的每个值)。
这是解决您第一个问题的dplyr
方法。
首先 group_by
你的 ID
列,然后使用 summarise
到 paste
并将它们折叠成单行 comma-separated 字符串每个 ID
对(并通过 na.omit
删除 NA
)。
最后,str_split
逗号分隔字符串删除重复元素,paste
将它们重新组合在一起,ungroup
.
library(dplyr)
df %>%
group_by(ID1, ID2) %>%
summarize(Values = paste0(na.omit(Value1), ",", na.omit(Value2), collapse = ",")) %>%
mutate(Values = paste0(unique(sort(str_split(Values, ",", simplify = T))), collapse = ",")) %>%
ungroup()
# A tibble: 2 × 3
ID1 ID2 Values
<int> <int> <chr>
1 1 2 calcium,sulfur,zinc
2 3 4 carbon,iron
数据
df <- read.table(header = T, text = "
ID1 ID2 Value1 Value2
1 2 zinc sulfur
1 2 zinc calcium
1 2 calcium NA
3 4 carbon iron
3 4 iron iron
3 4 iron carbon")
在 tidyverse
中,该过程是在 tidy
数据集中收集 value1 和 value2,group_by
您的 id 变量,以及 summarize
使用字符串的串联值。
library(tidyverse)
id1 <- c(1,1,1,3,3,3)
id2 <- c(2,2,2,4,4,4)
Value1 <- c("zinc", "zinc", "calcium", "carbon", "iron", "iron")
Value2 <- c("sulfer", "calcium", NA, "iron", "iron", "carbon")
df <- as_tibble(cbind(id1,id2,Value1,Value2))
df_cln <- df %>%
gather(var, value, -id1, -id2, na.rm = T) %>%
select(-var) %>%
unique() %>%
group_by(id1, id2) %>%
summarise(minerals=paste0(value, collapse=","))
print(df_cln)
# A tibble: 2 × 3
# Groups: id1 [2]
id1 id2 minerals
<chr> <chr> <chr>
1 1 2 zinc,calcium,sulfer
2 3 4 carbon,iron
这个呢?
data.frame(table(unlist(df[, sapply(df, is.character)])))
Var1 Freq
1 calcium 2
2 carbon 2
3 iron 4
4 sulfer 1
5 zinc 2
数据
df <- structure(list(ID1 = c(1, 1, 1, 3, 3, 3), ID2 = c(2, 2, 2, 4,
4, 4), Value1 = c("zinc", "zinc", "calcium", "carbon", "iron",
"iron"), Value2 = c("sulfer", "calcium", NA, "iron", "iron",
"carbon")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-6L))
# A tibble: 6 x 4
ID1 ID2 Value1 Value2
<dbl> <dbl> <chr> <chr>
1 1 2 zinc sulfer
2 1 2 zinc calcium
3 1 2 calcium NA
4 3 4 carbon iron
5 3 4 iron iron
6 3 4 iron carbon
使用 dplyr
的一个选项也是 t
排列 'Value' 列,在 toString
之后得到 unique
和 paste
分组
library(dplyr)
df %>%
group_by(ID1, ID2) %>%
summarise(Values = toString(na.omit(unique(c(t(across(starts_with("Value"))))))),
.groups = 'drop')
-输出
# A tibble: 2 × 3
ID1 ID2 Values
<int> <int> <chr>
1 1 2 zinc, sulfur, calcium
2 3 4 carbon, iron
我有一个包含 4 列的数据框
ID1 | ID2 | Value1 | Value2 |
---|---|---|---|
1 | 2 | zinc | sulfur |
1 | 2 | zinc | calcium |
1 | 2 | calcium | NA |
3 | 4 | carbon | iron |
3 | 4 | iron | iron |
3 | 4 | iron | carbon |
前两列始终对应,因此在配置时我基本上只需要使用其中一个 ID 列。
对于每对 ID,我希望每个值都对应于其中一个 ID,并且只出现一次。
所以对于上面的例子我想要:
ID1 | ID2 | Values |
---|---|---|
1 | 2 | zinc, sulfur, calcium |
3 | 4 | carbon, iron |
但是,如果列表仅列出每个 ID 的每个值(唯一出现)的次数,它也可能有效。
我最终想要的是每个Value在数据集中出现的次数
例如:
Value | Count |
---|---|
calcium | 1 |
carbon | 1 |
zinc | 1 |
iron | 1 |
sulfur | 1 |
我想列表可能是到达此端点的更好方法,但我更精通数据框。目前,我最感兴趣的是第一部分(获取 ID 对的每个值)。
这是解决您第一个问题的dplyr
方法。
首先 group_by
你的 ID
列,然后使用 summarise
到 paste
并将它们折叠成单行 comma-separated 字符串每个 ID
对(并通过 na.omit
删除 NA
)。
最后,str_split
逗号分隔字符串删除重复元素,paste
将它们重新组合在一起,ungroup
.
library(dplyr)
df %>%
group_by(ID1, ID2) %>%
summarize(Values = paste0(na.omit(Value1), ",", na.omit(Value2), collapse = ",")) %>%
mutate(Values = paste0(unique(sort(str_split(Values, ",", simplify = T))), collapse = ",")) %>%
ungroup()
# A tibble: 2 × 3
ID1 ID2 Values
<int> <int> <chr>
1 1 2 calcium,sulfur,zinc
2 3 4 carbon,iron
数据
df <- read.table(header = T, text = "
ID1 ID2 Value1 Value2
1 2 zinc sulfur
1 2 zinc calcium
1 2 calcium NA
3 4 carbon iron
3 4 iron iron
3 4 iron carbon")
在 tidyverse
中,该过程是在 tidy
数据集中收集 value1 和 value2,group_by
您的 id 变量,以及 summarize
使用字符串的串联值。
library(tidyverse)
id1 <- c(1,1,1,3,3,3)
id2 <- c(2,2,2,4,4,4)
Value1 <- c("zinc", "zinc", "calcium", "carbon", "iron", "iron")
Value2 <- c("sulfer", "calcium", NA, "iron", "iron", "carbon")
df <- as_tibble(cbind(id1,id2,Value1,Value2))
df_cln <- df %>%
gather(var, value, -id1, -id2, na.rm = T) %>%
select(-var) %>%
unique() %>%
group_by(id1, id2) %>%
summarise(minerals=paste0(value, collapse=","))
print(df_cln)
# A tibble: 2 × 3
# Groups: id1 [2]
id1 id2 minerals
<chr> <chr> <chr>
1 1 2 zinc,calcium,sulfer
2 3 4 carbon,iron
这个呢?
data.frame(table(unlist(df[, sapply(df, is.character)])))
Var1 Freq
1 calcium 2
2 carbon 2
3 iron 4
4 sulfer 1
5 zinc 2
数据
df <- structure(list(ID1 = c(1, 1, 1, 3, 3, 3), ID2 = c(2, 2, 2, 4,
4, 4), Value1 = c("zinc", "zinc", "calcium", "carbon", "iron",
"iron"), Value2 = c("sulfer", "calcium", NA, "iron", "iron",
"carbon")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-6L))
# A tibble: 6 x 4
ID1 ID2 Value1 Value2
<dbl> <dbl> <chr> <chr>
1 1 2 zinc sulfer
2 1 2 zinc calcium
3 1 2 calcium NA
4 3 4 carbon iron
5 3 4 iron iron
6 3 4 iron carbon
使用 dplyr
的一个选项也是 t
排列 'Value' 列,在 toString
之后得到 unique
和 paste
分组
library(dplyr)
df %>%
group_by(ID1, ID2) %>%
summarise(Values = toString(na.omit(unique(c(t(across(starts_with("Value"))))))),
.groups = 'drop')
-输出
# A tibble: 2 × 3
ID1 ID2 Values
<int> <int> <chr>
1 1 2 zinc, sulfur, calcium
2 3 4 carbon, iron