基于查找向量的条件重新编码
Conditional recode based on lookup vector
我需要根据查找向量有条件地重新编码我的数据帧 d
。
dput(lookup)
structure(c("Apple", "Apple", "Banana", "Carrot"), .Names = c("101", "102", "102", "103"))
dput(d)
structure(list(pat = c(101, 101, 101, 102, 102, 103), gene = structure(1:6, .Label = c("a",
"b", "c", "d", "e", "f"), class = "factor"), Apple = c(0.1, 0.2,
0.3, 0.4, NA, NA), Banana = c(NA, NA, NA, NA, 0.55, NA), Carrot = c(NA,
NA, NA, NA, NA, 0.6)), .Names = c("pat", "gene", "Apple", "Banana",
"Carrot"), row.names = c(NA, -6L), class = "data.frame")
d
是我通过reshape
得到的宽数据框。如果 pat
根据查找 table。在这种情况下,d$Apple[5]
和 d$Banana[4]
将被重新编码为 0
。
我一直在研究 dplyr
中的 recode
,但我不知道如何查找和重新编码,更不用说它必须在多个列上完成了。 . recoding variables in R with a lookup table 上还有另一个相关的 post 但它似乎不适用于我的问题。谁能帮我吗?谢谢!
编辑
我尝试了以下方法:。
e <- melt(d, id.vars=c("pat", "gene"))
e %>% mutate(test=ifelse(lookup[as.character(pat)] == variable, replace(value, is.na(value), 0), value))
我的代码部分有效。它成功地在 d$Apple[5]
中重新编码 NA
但在 d$Banana[4]
中没有,因为查找只能给出第一个值:
lookup["102"]
102
"Apple"
而我需要我的查找能够同时输出 "Apple" 和 "Banana" 并能够转换 NAs
相应地满足每个条件。有什么想法吗?
可能有点不完整,但我设法通过循环创建了一个可能的解决方案
for(i in 1:nrow(d)){
mtch <- lookup[which(d$pat[i] == names(lookup))] # Get lookup matches for row i
colnum <- which(colnames(d) %in% mtch) # Get column nr that matches lookup value
newval<-ifelse(is.na(d[i,colnum]),0,d[i,colnum]) # if it contains NA replace with 0
d[i,colnum]<-unlist(newval) # replace the values
}
输出
pat gene Apple Banana Carrot
1 101 a 0.1 NA NA
2 101 b 0.2 NA NA
3 101 c 0.3 NA NA
4 102 d 0.4 0.00 NA
5 102 e 0.0 0.55 NA
6 103 f NA NA 0.6
希望对您有所帮助
我会使用长格式并使用来自 dplyr
的连接。
我会先回到长格式,如下所示:
library(tidyverse)
long_format <- d %>%
gather(fruit, value, -pat, -gene)
然后我会将查找创建为 data_frame
,这样我们就可以使用联接。
lookup <- tribble(~pat, ~fruit,
101, "Apple",
102, "Apple",
102, "Banana",
103, "Carrot")
使用 right_join
方法,我们保留查找中的所有组合。然后我们用 0
替换缺失值并传播回宽格式,以备不时之需。
long_format %>%
right_join(lookup) %>%
replace_na(replace = list(value = 0)) %>%
spread(fruit, value)
#> Joining, by = c("pat", "fruit")
#> pat gene Apple Banana Carrot
#> 1 101 a 0.1 NA NA
#> 2 101 b 0.2 NA NA
#> 3 101 c 0.3 NA NA
#> 4 102 d 0.4 0.00 NA
#> 5 102 e 0.0 0.55 NA
#> 6 103 f NA NA 0.6
抱歉,这里没有 dplyr
但代码相当简单。
for(i in unique(lookup)){
need_to_replace = is.na(d[[i]]) & (d$pat %in% names(lookup[lookup %in% i]))
d[[i]][need_to_replace] = 0
}
d
pat gene Apple Banana Carrot
1 101 a 0.1 NA NA
2 101 b 0.2 NA NA
3 101 c 0.3 NA NA
4 102 d 0.4 0.00 NA
5 102 e 0.0 0.55 NA
6 103 f NA NA 0.6
我需要根据查找向量有条件地重新编码我的数据帧 d
。
dput(lookup)
structure(c("Apple", "Apple", "Banana", "Carrot"), .Names = c("101", "102", "102", "103"))
dput(d)
structure(list(pat = c(101, 101, 101, 102, 102, 103), gene = structure(1:6, .Label = c("a",
"b", "c", "d", "e", "f"), class = "factor"), Apple = c(0.1, 0.2,
0.3, 0.4, NA, NA), Banana = c(NA, NA, NA, NA, 0.55, NA), Carrot = c(NA,
NA, NA, NA, NA, 0.6)), .Names = c("pat", "gene", "Apple", "Banana",
"Carrot"), row.names = c(NA, -6L), class = "data.frame")
d
是我通过reshape
得到的宽数据框。如果 pat
根据查找 table。在这种情况下,d$Apple[5]
和 d$Banana[4]
将被重新编码为 0
。
我一直在研究 dplyr
中的 recode
,但我不知道如何查找和重新编码,更不用说它必须在多个列上完成了。 . recoding variables in R with a lookup table 上还有另一个相关的 post 但它似乎不适用于我的问题。谁能帮我吗?谢谢!
编辑
我尝试了以下方法:。
e <- melt(d, id.vars=c("pat", "gene"))
e %>% mutate(test=ifelse(lookup[as.character(pat)] == variable, replace(value, is.na(value), 0), value))
我的代码部分有效。它成功地在 d$Apple[5]
中重新编码 NA
但在 d$Banana[4]
中没有,因为查找只能给出第一个值:
lookup["102"]
102
"Apple"
而我需要我的查找能够同时输出 "Apple" 和 "Banana" 并能够转换 NAs
相应地满足每个条件。有什么想法吗?
可能有点不完整,但我设法通过循环创建了一个可能的解决方案
for(i in 1:nrow(d)){
mtch <- lookup[which(d$pat[i] == names(lookup))] # Get lookup matches for row i
colnum <- which(colnames(d) %in% mtch) # Get column nr that matches lookup value
newval<-ifelse(is.na(d[i,colnum]),0,d[i,colnum]) # if it contains NA replace with 0
d[i,colnum]<-unlist(newval) # replace the values
}
输出
pat gene Apple Banana Carrot
1 101 a 0.1 NA NA
2 101 b 0.2 NA NA
3 101 c 0.3 NA NA
4 102 d 0.4 0.00 NA
5 102 e 0.0 0.55 NA
6 103 f NA NA 0.6
希望对您有所帮助
我会使用长格式并使用来自 dplyr
的连接。
我会先回到长格式,如下所示:
library(tidyverse)
long_format <- d %>%
gather(fruit, value, -pat, -gene)
然后我会将查找创建为 data_frame
,这样我们就可以使用联接。
lookup <- tribble(~pat, ~fruit,
101, "Apple",
102, "Apple",
102, "Banana",
103, "Carrot")
使用 right_join
方法,我们保留查找中的所有组合。然后我们用 0
替换缺失值并传播回宽格式,以备不时之需。
long_format %>%
right_join(lookup) %>%
replace_na(replace = list(value = 0)) %>%
spread(fruit, value)
#> Joining, by = c("pat", "fruit")
#> pat gene Apple Banana Carrot
#> 1 101 a 0.1 NA NA
#> 2 101 b 0.2 NA NA
#> 3 101 c 0.3 NA NA
#> 4 102 d 0.4 0.00 NA
#> 5 102 e 0.0 0.55 NA
#> 6 103 f NA NA 0.6
抱歉,这里没有 dplyr
但代码相当简单。
for(i in unique(lookup)){
need_to_replace = is.na(d[[i]]) & (d$pat %in% names(lookup[lookup %in% i]))
d[[i]][need_to_replace] = 0
}
d
pat gene Apple Banana Carrot
1 101 a 0.1 NA NA
2 101 b 0.2 NA NA
3 101 c 0.3 NA NA
4 102 d 0.4 0.00 NA
5 102 e 0.0 0.55 NA
6 103 f NA NA 0.6