[R崩溃多行到1行使用特定的功能,日期和字符列
问题描述:
library(data.table)
library(lubridate)
x1 <- c(20090101, "2009-01-02", "2009 01 03", "2009-1-4",
"2009-1, 5", "Created on 2009 1 6", "200901 !!! 07")
dt2 <- data.table(id = c(1,1,1,2,2,2,2), date1 = ymd(x1), charval = c("aa","vv","ss","a","b","c","d"))
id date1 charval
1: 1 2009-01-01 aa
2: 1 2009-01-02 vv
3: 1 2009-01-03 ss
4: 2 2009-01-04 a
5: 2 2009-01-05 b
6: 2 2009-01-06 c
7: 2 2009-01-07 d
我用下面的代码通过ID分组:[R崩溃多行到1行使用特定的功能,日期和字符列
dt3 <- dt2[, Map(function(x,y) ifelse(x != "paste", get(x)(y, na.rm = TRUE), paste(y, sep = ";")),
setNames(c("mean", "paste"), names(.SD)), .SD), by = id]
得到的东西是这样的:
id date1 charval
1: 1 2009-01-02 aa;vv;ss
2: 2 2009-01-05 a;b;c;d
但实际上我看到下一个结果:
id date1 charval
1: 1 NA aa
2: 2 NA a
1)我不明白为什么粘贴不工作 2)我不明白为什么平均值(日期1)不工作 因为例如下面的代码工作正常:
mean(dt2$date1)
[1] "2009-01-04"
答
为什么我们要经过Map
目前尚不清楚和get
。通过 'ID' 分组后,得到 '日期1' 和paste
的 'charval' 在一起的mean
dt2[, .(date1 = mean(date1), charval = toString(charval)), id]
# id date1 charval
#1: 1 2009-01-02 aa, vv, ss
#2: 2 2009-01-05 a, b, c, d
注:toString
是paste(..., collapse=', ')
dt2[, .(date1 = mean(date1), charval = paste(charval, collapse=";")), id]
# id date1 charval
#1: 1 2009-01-02 aa;vv;ss
#2: 2 2009-01-05 a;b;c;d
由于OP的问题是关于Map
使用get
拨打mean
。这似乎是触发
如果(!is.numeric(x)的& &!is.complex(x)的& &!is.logical(X)){ 警告(“的说法是不是数字或逻辑:返回NA“) 回报(NA_real_)
并且当它发现‘日期1’是Date
类虽然被存储为numeric
返回NA。一种选择是指定envir
中的get
另一个问题是使用ifelse
。这是更好地使用if/else
,因为只有两个元素
dt2[, Map(function(x, y) if(x != "paste") get(x, envir = parent.frame())(y, na.rm = TRUE)
else paste(y, collapse=':'), setNames(c("mean", "paste"), names(.SD)), .SD), by = id]
# id date1 charval
#1: 1 2009-01-02 aa:vv:ss
#2: 2 2009-01-05 a:b:c:d
get
是棘手的一种,如果指定正确的环境,它按预期工作
get("mean")(dt2$date1)
#[1] "2009-01-04"
或代替if/else
到“粘贴”字符串,我们可以查看列class
,如果它是character
,则执行paste
或返回mean
dt2[, Map(function(x, y) if(is.character(y)) get(x)(y, collapse=":")
else get(x, envir = parent.frame())(y, na.rm = TRUE),
setNames(c("mean", "paste"), names(.SD)), .SD), by = id]
# id date1 charval
#1: 1 2009-01-02 aa:vv:ss
#2: 2 2009-01-05 a:b:c:d
请注意,最好使用第一种方法而不用麻烦