![](/img/trans.png)
[英]Create a new column in dplyr by appending values to a list from other columns?
[英]dplyr & tibble - Create a new column according to values in a list column
我有一個小數據框,如下所示:
data = tibble(X = c("a", "b", "c", "d","c"),
Y = c("a1", "b1", "c1", "d1","c1"),
Z = c("a2", "b2", "c2", "d2","c2"),
all = list(c("a"), c("b"), c("c", "c1"), c("d", "d2"), c("c", "b2")))
我想創建一個新列“結果”,以便為每一行:
-如果“ Y”值在“ all”中=>結果等於Y值
-如果“ Z”值在“ all”中=>結果等於Z值
-否則結果等於“無”
我已經嘗試使用dplyr語法編寫以下代碼。
data %>%
mutate(result = case_when(Y %in% all ~ Y,
Z %in% all ~ Z,
TRUE ~ "none"))
它無法按預期方式工作並返回:
# A tibble: 4 x 5
X Y Z all result
<chr> <chr> <chr> <list> <chr>
1 a a1 a2 <chr [2]> none
2 b b1 b2 <chr [1]> none
3 c c1 c2 <chr [2]> none
4 d d1 d2 <chr [2]> none
當我想獲得:
# A tibble: 4 x 5
X Y Z all result
<chr> <chr> <chr> <list> <chr>
1 a a1 a2 <chr [2]> none
2 b b1 b2 <chr [1]> none
3 c c1 c2 <chr [2]> c1
4 d d1 d2 <chr [2]> d2
編輯
一個問題是要取消列出列列表中的值,如Ronak Shah所述 。 但是即使采用這種解決方案,其行為也像在列列表上工作時將考慮列的所有值,而不僅僅是行的值。
這是我從建議的解決方案和編輯后的數據中獲得的信息:
data %>%
mutate(result = case_when(Y %in% flatten_chr(all) ~ Y,
Z %in% flatten_chr(all) ~ Z,
TRUE ~ "none"))
# A tibble: 5 x 5
X Y Z all result
<chr> <chr> <chr> <list> <chr>
1 a a1 a2 <chr [1]> none
2 b b1 b2 <chr [1]> b2
3 c c1 c2 <chr [2]> c1
4 d d1 d2 <chr [2]> d2
5 c c1 c2 <chr [2]> c1
什么時候應該返回:
# A tibble: 5 x 5
X Y Z all result
<chr> <chr> <chr> <list> <chr>
1 a a1 a2 <chr [1]> none
2 b b1 b2 <chr [1]> none
3 c c1 c2 <chr [2]> c1
4 d d1 d2 <chr [2]> d2
5 c c1 c2 <chr [2]> none
all
列實際上是一個list
,您不能直接比較list列中的值。
例如,
"a" %in% list(c("a", "b"))
#[1] FALSE
您需要unlist
或flatten_chr
使其起作用。
"a" %in% unlist(list(c("a", "b")))
#[1] TRUE
"a" %in% flatten_chr(list(c("a", "b")))
#[1] TRUE
所以,現在你可以
library(tidyverse)
data %>%
mutate(result = case_when(Y %in% flatten_chr(all) ~ Y,
Z %in% flatten_chr(all) ~ Z,
TRUE ~ "none"))
# X Y Z all result
# <chr> <chr> <chr> <list> <chr>
#1 a a1 a2 <chr [2]> none
#2 b b1 b2 <chr [1]> none
#3 c c1 c2 <chr [2]> c1
#4 d d1 d2 <chr [2]> d2
編輯
您可以rowwise
添加以比較每行的值。
data %>%
rowwise() %>%
mutate(result = case_when(Y %in% all ~ Y,
Z %in% all ~ Z,
TRUE ~ "none"))
# A tibble: 5 x 5
# X Y Z all result
# <chr> <chr> <chr> <list> <chr>
#1 a a1 a2 <chr [1]> none
#2 b b1 b2 <chr [1]> none
#3 c c1 c2 <chr [2]> c1
#4 d d1 d2 <chr [2]> d2
#5 c c1 c2 <chr [2]> none
我使用過ifelse
和mapply
以及any
要遍歷列表並根據給定條件生成值的方法,如下所示
data$result <- ifelse(unlist(mapply(
data$all,data$Z,
FUN = function(x, y) {
any(x%in% y)
}
)), data$Z, ifelse(unlist(mapply(
data$all, data$Y,
FUN = function(x, y) {
any(x%in% y)
}
)), data$Y, "none"))
#View Data
data
或者:
library(dplyr)
data %>%
mutate(result = ifelse(unlist(mapply(
all,Z,
FUN = function(x,y) {
any(x%in% y)
}
)), Z, ifelse(unlist(mapply(
all,Y,
FUN = function(x, y) {
any(x%in% y)
}
)), Y, "none")))
這產生
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.