我有4个日期变量和1个分组变量。根据分组变量中的值,需要将日期放入新变量中。 我的数据如下:(https://www.dropbox.com/s/wlfv89qc1jzwfgk/vb.JPG)
我想根据group的值创建一个新变量。当组为A时,我需要date1;当组为B时,我需要date2,依此类推。
这是我使用的代码:
+
此代码给我警告消息:
(如果if(tabel $ group == 1){: 条件的长度> 1,并且只会使用第一个元素
答案 0 :(得分:0)
您需要按行执行此操作...一个选项是使用嵌套的ifelse()
newvar=ifelse(tabel$group=='A',tabel$date1,
ifelse(tabel$group=='B',tabel$date2,
ifelse(tabel$group=='C',tabel$date3,tabel$date4))))
答案 1 :(得分:0)
我确信之前已经多次询问并回答了这个问题,但是我没有找到很好的副本。
嵌套ifelse()
并不总是最好的解决方案。编写,阅读和维护很多括号很麻烦。此外,ifelse()
可能会意外更改结果的类型,例如类Date
。
所以,我想发布一些替代方法
match()
进行子设置这个人使用了一个特殊的事实,即第一个字母“ A”对应于第一个日期列date1
,依此类推。因此,它可能通常不适用:
indices <- matrix(c(seq.int(nrow(tabel)), match(tabel$group, LETTERS[1:4])), ncol = 2)
newvar <- tabel[, -1][indices]
newvar
[1] "2011-01-01" "2011-01-02" "2011-01-03" "2012-02-04" "2012-02-05" "2012-02-06" "2013-03-07" "2013-03-08" "2013-03-09" [10] "2014-04-10" "2014-04-11" "2014-04-12"
用于子设置的indices
(行号,列号)是:
[,1] [,2] [1,] 1 1 [2,] 2 1 [3,] 3 1 [4,] 4 2 [5,] 5 2 [6,] 6 2 [7,] 7 3 [8,] 8 3 [9,] 9 3 [10,] 10 4 [11,] 11 4 [12,] 12 4
tabel[, -1]
省略了第一列(group
)。
case_when()
这是来自if_else()
包的多个dplyr
语句的向量化版本。
newvar <- dplyr::case_when(
tabel$group == "A" ~ tabel$date1,
tabel$group == "B" ~ tabel$date2,
tabel$group == "C" ~ tabel$date3,
tabel$group == "D" ~ tabel$date4)
或
library(dplyr)
newvar <- tabel %>%
transmute(value = case_when(group == "A" ~ date1,
group == "B" ~ date2,
group == "C" ~ date3,
group == "D" ~ date4)) %>%
pull(value)
data.table
联接查找表查找表将group
与列名之间的关系视为数据,因此易于创建和维护。另一方面,tabel
必须从宽格式改成长格式,然后才能与lookup
结合使用:
library(data.table)
lookup <- data.table(group = LETTERS[1:4], variable = paste0("date", 1:4))
newvar <- melt(setDT(tabel), id.vars = "group")[lookup, on = .(group, variable)]$value
lookup
group variable 1: A date1 2: B date2 3: C date3 4: D date4
重塑的长格式为
melt(setDT(tabel), id.vars = "group")
group variable value 1: A date1 2011-01-01 2: A date1 2011-01-02 3: A date1 2011-01-03 4: B date1 2011-01-04 5: B date1 2011-01-05 6: B date1 2011-01-06 7: C date1 2011-01-07 8: C date1 2011-01-08 9: C date1 2011-01-09 10: D date1 2011-01-10 11: D date1 2011-01-11 12: D date1 2011-01-12 13: A date2 2012-02-01 14: A date2 2012-02-02 15: A date2 2012-02-03 16: B date2 2012-02-04 17: B date2 2012-02-05 18: B date2 2012-02-06 19: C date2 2012-02-07 20: C date2 2012-02-08 21: C date2 2012-02-09 22: D date2 2012-02-10 23: D date2 2012-02-11 24: D date2 2012-02-12 25: A date3 2013-03-01 26: A date3 2013-03-02 27: A date3 2013-03-03 28: B date3 2013-03-04 29: B date3 2013-03-05 30: B date3 2013-03-06 31: C date3 2013-03-07 32: C date3 2013-03-08 33: C date3 2013-03-09 34: D date3 2013-03-10 35: D date3 2013-03-11 36: D date3 2013-03-12 37: A date4 2014-04-01 38: A date4 2014-04-02 39: A date4 2014-04-03 40: B date4 2014-04-04 41: B date4 2014-04-05 42: B date4 2014-04-06 43: C date4 2014-04-07 44: C date4 2014-04-08 45: C date4 2014-04-09 46: D date4 2014-04-10 47: D date4 2014-04-11 48: D date4 2014-04-12 group variable value
dplyr
和tidyr
结合查找表library(dplyr)
library(tidyr)
lookup <- tibble(group = LETTERS[1:4], key = paste0("date", 1:4))
newvar <- tabel %>%
gather(key, value, -group) %>%
inner_join(lookup) %>%
pull(value)
这与上面的工作原理相同:创建查找表,从宽格式改成长格式并合并。 pull()
返回一个简单的结果向量。
tabel <- data.frame(group = rep(LETTERS[1:4], each = 3L),
date1 = as.Date("2011-01-01") + 0:11,
date2 = as.Date("2012-02-01") + 0:11,
date3 = as.Date("2013-03-01") + 0:11,
date4 = as.Date("2014-04-01") + 0:11)
tabel
group date1 date2 date3 date4 1: A 2011-01-01 2012-02-01 2013-03-01 2014-04-01 2: A 2011-01-02 2012-02-02 2013-03-02 2014-04-02 3: A 2011-01-03 2012-02-03 2013-03-03 2014-04-03 4: B 2011-01-04 2012-02-04 2013-03-04 2014-04-04 5: B 2011-01-05 2012-02-05 2013-03-05 2014-04-05 6: B 2011-01-06 2012-02-06 2013-03-06 2014-04-06 7: C 2011-01-07 2012-02-07 2013-03-07 2014-04-07 8: C 2011-01-08 2012-02-08 2013-03-08 2014-04-08 9: C 2011-01-09 2012-02-09 2013-03-09 2014-04-09 10: D 2011-01-10 2012-02-10 2013-03-10 2014-04-10 11: D 2011-01-11 2012-02-11 2013-03-11 2014-04-11 12: D 2011-01-12 2012-02-12 2013-03-12 2014-04-12