我有一个小数据框,如下所示:
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
答案 0 :(得分:4)
all
列实际上是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
答案 1 :(得分:0)
我已使用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")))
这产生