将数据框中的列与部分信息组合在一起
Combining columns in a dataframe each with partial information
我有一个大数据集,它在不同时间段对相同变量使用不同的编码方案。每个时间段的编码表示为一列,其中包含它活跃的那一年的值,而其他地方则为 NA。
我能够 "combine" 通过使用嵌套的 ifelse 命令和 dplyr 的 mutate [见下面的编辑] 来 "combine" 它们,但是我 运行 遇到了使用 ifelse 做一些稍微不同的事情的问题。我想根据之前的任何变量是否满足条件来编写一个新变量。但由于某种原因,下面的 ifelse 结构不起作用。
MWE:
library("dplyr")
library("magrittr")
df <- data.frame(id = 1:12, year = c(rep(1995, 5), rep(1996, 5), rep(1997, 2)), varA = c("A","C","A","C","B",rep(NA,7)), varB = c(rep(NA,5),"B","A","C","A","B",rep(NA,2)))
df %>% mutate(varC = ifelse(varA == "C" | varB == "C", "C", "D"))
输出:
> df
id year varA varB varC
1 1 1995 A <NA> <NA>
2 2 1995 C <NA> C
3 3 1995 A <NA> <NA>
4 4 1995 C <NA> C
5 5 1995 B <NA> <NA>
6 6 1996 <NA> B <NA>
7 7 1996 <NA> A <NA>
8 8 1996 <NA> C C
9 9 1996 <NA> A <NA>
10 10 1996 <NA> B <NA>
11 11 1997 <NA> <NA> <NA>
12 12 1997 <NA> <NA> <NA>
如果我不使用 |
运算符,并且仅针对 varA 进行测试,它会得出预期的结果,但它仅适用于 varA 不为 NA 的年份。
输出:
> df %<>% mutate(varC = ifelse(varA == "C", "C", "D"))
> df
id year varA varB varC
1 1 1995 A <NA> D
2 2 1995 C <NA> C
3 3 1995 A <NA> D
4 4 1995 C <NA> C
5 5 1995 B <NA> D
6 6 1996 <NA> B <NA>
7 7 1996 <NA> A <NA>
8 8 1996 <NA> C <NA>
9 9 1996 <NA> A <NA>
10 10 1996 <NA> B <NA>
11 11 1997 <NA> <NA> <NA>
12 12 1997 <NA> <NA> <NA>
期望的输出:
> df
id year varA varB varC
1 1 1995 A <NA> D
2 2 1995 C <NA> C
3 3 1995 A <NA> D
4 4 1995 C <NA> C
5 5 1995 B <NA> D
6 6 1996 <NA> B D
7 7 1996 <NA> A D
8 8 1996 <NA> C C
9 9 1996 <NA> A D
10 10 1996 <NA> B D
11 11 1997 <NA> <NA> <NA>
12 12 1997 <NA> <NA> <NA>
我怎样才能得到我要找的东西?
为了让这个问题更适用于更广泛的受众,并从这种情况中吸取教训,最好能解释一下使用 |
进行比较导致它不起作用的原因正如预期的那样。提前致谢!
编辑:这就是我将它们与嵌套 ifelses 成功组合的意思
> df %>% mutate(varC = ifelse(year == 1995, as.character(varA),
+ ifelse(year == 1996, as.character(varB), NA)))
id year varA varB varC
1 1 1995 A <NA> A
2 2 1995 C <NA> C
3 3 1995 A <NA> A
4 4 1995 C <NA> C
5 5 1995 B <NA> B
6 6 1996 <NA> B B
7 7 1996 <NA> A A
8 8 1996 <NA> C C
9 9 1996 <NA> A A
10 10 1996 <NA> B B
11 11 1997 <NA> <NA> <NA>
12 12 1997 <NA> <NA> <NA>
根据@Khashaa 评论。这应该可以解决问题并让您获得所需的输出。
df %>%
mutate(varC = ifelse(is.na(varA) & is.na(varB), NA,
ifelse(varA %in% "C" | varB %in% "C", "C", "D")))
R 有这种烦人的倾向,其中涉及 NA 的条件的逻辑值只是 NA,而不是 true 或 false。
即 NA>0 = NA 而不是 FALSE
NA 与 TRUE 的交互就像 false 一样。即 TRUE|NA = TRUE。 TRUE&NA = NA.
有趣的是,它还与 FALSE 交互,就好像它是 TRUE 一样。即 FALSE|NA=NA。假&NA=假
其实NA就像一个介于TRUE和FALSE之间的逻辑值。例如不适用|真|假 = 真。
所以这里有一个破解方法:
ifelse((varA=='C'&!is.na(varA))|(varB=='C'&!is.na(varB))
我们如何解释这一点?在 OR 的左侧,我们有以下内容:如果 varA 为 NA,则我们有 NA&FALSE。由于 NA 在逻辑层次结构中比 FALSE 高一级,& 将强制整个事物为 FALSE。否则,如果 varA 不是 NA 但不是 'C',您将得到 FALSE&TRUE,它会根据需要给出 FALSE。否则,如果它是 'C',它们都为真。 OR右边的东西也是一样。
当使用涉及x但x可以为NA的条件时,我喜欢使用
((condition for x)&!is.na(x)) 完全排除 NA 输出并在我想要的情况下强制使用 TRUE 或 FALSE 值。
编辑:我只记得如果它们都是 NA,您需要 NA 输出。这并没有结束,所以这是我的错。除非当它们都是 NA 时你对 'D' 输出没意见。
EDIT2:这应该根据需要输出 NA:
ifelse(is.na(varA)&is.na(varB), NA, ifelse((varA=='C'&!is.na(varA))|(varB=='C'&!is.na(varB)), 'C','D'))
我有一个大数据集,它在不同时间段对相同变量使用不同的编码方案。每个时间段的编码表示为一列,其中包含它活跃的那一年的值,而其他地方则为 NA。
我能够 "combine" 通过使用嵌套的 ifelse 命令和 dplyr 的 mutate [见下面的编辑] 来 "combine" 它们,但是我 运行 遇到了使用 ifelse 做一些稍微不同的事情的问题。我想根据之前的任何变量是否满足条件来编写一个新变量。但由于某种原因,下面的 ifelse 结构不起作用。
MWE:
library("dplyr")
library("magrittr")
df <- data.frame(id = 1:12, year = c(rep(1995, 5), rep(1996, 5), rep(1997, 2)), varA = c("A","C","A","C","B",rep(NA,7)), varB = c(rep(NA,5),"B","A","C","A","B",rep(NA,2)))
df %>% mutate(varC = ifelse(varA == "C" | varB == "C", "C", "D"))
输出:
> df
id year varA varB varC
1 1 1995 A <NA> <NA>
2 2 1995 C <NA> C
3 3 1995 A <NA> <NA>
4 4 1995 C <NA> C
5 5 1995 B <NA> <NA>
6 6 1996 <NA> B <NA>
7 7 1996 <NA> A <NA>
8 8 1996 <NA> C C
9 9 1996 <NA> A <NA>
10 10 1996 <NA> B <NA>
11 11 1997 <NA> <NA> <NA>
12 12 1997 <NA> <NA> <NA>
如果我不使用 |
运算符,并且仅针对 varA 进行测试,它会得出预期的结果,但它仅适用于 varA 不为 NA 的年份。
输出:
> df %<>% mutate(varC = ifelse(varA == "C", "C", "D"))
> df
id year varA varB varC
1 1 1995 A <NA> D
2 2 1995 C <NA> C
3 3 1995 A <NA> D
4 4 1995 C <NA> C
5 5 1995 B <NA> D
6 6 1996 <NA> B <NA>
7 7 1996 <NA> A <NA>
8 8 1996 <NA> C <NA>
9 9 1996 <NA> A <NA>
10 10 1996 <NA> B <NA>
11 11 1997 <NA> <NA> <NA>
12 12 1997 <NA> <NA> <NA>
期望的输出:
> df
id year varA varB varC
1 1 1995 A <NA> D
2 2 1995 C <NA> C
3 3 1995 A <NA> D
4 4 1995 C <NA> C
5 5 1995 B <NA> D
6 6 1996 <NA> B D
7 7 1996 <NA> A D
8 8 1996 <NA> C C
9 9 1996 <NA> A D
10 10 1996 <NA> B D
11 11 1997 <NA> <NA> <NA>
12 12 1997 <NA> <NA> <NA>
我怎样才能得到我要找的东西?
为了让这个问题更适用于更广泛的受众,并从这种情况中吸取教训,最好能解释一下使用 |
进行比较导致它不起作用的原因正如预期的那样。提前致谢!
编辑:这就是我将它们与嵌套 ifelses 成功组合的意思
> df %>% mutate(varC = ifelse(year == 1995, as.character(varA),
+ ifelse(year == 1996, as.character(varB), NA)))
id year varA varB varC
1 1 1995 A <NA> A
2 2 1995 C <NA> C
3 3 1995 A <NA> A
4 4 1995 C <NA> C
5 5 1995 B <NA> B
6 6 1996 <NA> B B
7 7 1996 <NA> A A
8 8 1996 <NA> C C
9 9 1996 <NA> A A
10 10 1996 <NA> B B
11 11 1997 <NA> <NA> <NA>
12 12 1997 <NA> <NA> <NA>
根据@Khashaa 评论。这应该可以解决问题并让您获得所需的输出。
df %>%
mutate(varC = ifelse(is.na(varA) & is.na(varB), NA,
ifelse(varA %in% "C" | varB %in% "C", "C", "D")))
R 有这种烦人的倾向,其中涉及 NA 的条件的逻辑值只是 NA,而不是 true 或 false。 即 NA>0 = NA 而不是 FALSE
NA 与 TRUE 的交互就像 false 一样。即 TRUE|NA = TRUE。 TRUE&NA = NA.
有趣的是,它还与 FALSE 交互,就好像它是 TRUE 一样。即 FALSE|NA=NA。假&NA=假
其实NA就像一个介于TRUE和FALSE之间的逻辑值。例如不适用|真|假 = 真。
所以这里有一个破解方法:
ifelse((varA=='C'&!is.na(varA))|(varB=='C'&!is.na(varB))
我们如何解释这一点?在 OR 的左侧,我们有以下内容:如果 varA 为 NA,则我们有 NA&FALSE。由于 NA 在逻辑层次结构中比 FALSE 高一级,& 将强制整个事物为 FALSE。否则,如果 varA 不是 NA 但不是 'C',您将得到 FALSE&TRUE,它会根据需要给出 FALSE。否则,如果它是 'C',它们都为真。 OR右边的东西也是一样。
当使用涉及x但x可以为NA的条件时,我喜欢使用 ((condition for x)&!is.na(x)) 完全排除 NA 输出并在我想要的情况下强制使用 TRUE 或 FALSE 值。
编辑:我只记得如果它们都是 NA,您需要 NA 输出。这并没有结束,所以这是我的错。除非当它们都是 NA 时你对 'D' 输出没意见。
EDIT2:这应该根据需要输出 NA:
ifelse(is.na(varA)&is.na(varB), NA, ifelse((varA=='C'&!is.na(varA))|(varB=='C'&!is.na(varB)), 'C','D'))