leo*_*ido 5 grouping r data.table
给定一个data.table对象,我会将一些分组列的值折叠成一个对象,并将生成的对象插入到一个新的列中.
dt <- data.table(
c('A|A', 'B|A', 'A|A', 'B|A', 'A|B'),
c(0, 0, 1, 1, 0),
c(22.7, 1.2, 0.3, 0.4, 0.0)
)
setnames(dt, names(dt), c('GROUPING', 'NAME', 'VALUE'))
dt
# GROUPING NAME VALUE
# 1: A|A 0 22.7
# 2: B|A 0 1.2
# 3: A|A 1 0.3
# 4: B|A 1 0.4
# 5: A|B 0 0.0
Run Code Online (Sandbox Code Playgroud)
我认为要做到这一点首先需要指定要分组的列,所以我应该从类似的东西开始dt[, OBJECTS := <expr>, by = GROUPING].
不幸的是,我不知道<expr>要使用的表达式,结果如下:
# GROUPING OBJECTS
# 1: A|A <vector>
# 2: B|A <vector>
# 3: A|B <vector>
Run Code Online (Sandbox Code Playgroud)
每个<vector>必须包含其他列的值.例如,第一个<vector>必须是一个命名向量,相当于:
eg <- c(22.7, 0.3)
names(eg) <- c('0', '1')
# 0 1
# 22.7 0.3
Run Code Online (Sandbox Code Playgroud)
在其中工作j:如果要将列的值设为向量,则需要将输出包装在中list(.).
j本身需要调用list,所以你的最终表达式将类似于嵌套list,例如:
dt[, list(allNames=list(NAME), allValues=list(VALUE)), by=GROUPING]
# GROUPING allNames allValues
# 1: A|A 0,1 22.7,0.3
# 2: B|A 0,1 1.2,0.4
# 3: A|B 0 0
Run Code Online (Sandbox Code Playgroud)
正如@Mnel指出的那样,相当于:
dt[, lapply(.SD, list), by=GROUPING]
Run Code Online (Sandbox Code Playgroud)
如果你想要它的长形式,那么你的结构<expr>将是:
list( c( list(), list(), ..., list() ) ) 例如:
dt[, list(c(list(NAME), list(VALUE))), by=GROUPING]
# GROUPING V1
# 1: A|A 0,1
# 2: A|A 22.7,0.3
# 3: B|A 0,1
# 4: B|A 1.2,0.4
# 5: A|B 0
# 6: A|B 0
Run Code Online (Sandbox Code Playgroud)
或等效地:
dt[, list(lapply(.SD, c)), by=GROUPING]
Run Code Online (Sandbox Code Playgroud)
我认为这就是您正在寻找的:
\n\ndt1 <- dt[, list(list(setNames(VALUE, NAME))), by = GROUPING]\ndt1\n# GROUPING V1\n# 1: A|A 22.7,0.3\n# 2: B|A 1.2,0.4\n# 3: A|B 0\nstr(dt1)\n# Classes \xe2\x80\x98data.table\xe2\x80\x99 and \'data.frame\': 3 obs. of 2 variables:\n# $ GROUPING: chr "A|A" "B|A" "A|B"\n# $ V1 :List of 3\n# ..$ : Named num 22.7 0.3\n# .. ..- attr(*, "names")= chr "0" "1"\n# ..$ : Named num 1.2 0.4\n# .. ..- attr(*, "names")= chr "0" "1"\n# ..$ : Named num 0\n# .. ..- attr(*, "names")= chr "0"\n# - attr(*, ".internal.selfref")=<externalptr> \ndt1$V1\n# [[1]]\n# 0 1 \n# 22.7 0.3 \n# \n# [[2]]\n# 0 1 \n# 1.2 0.4 \n# \n# [[3]]\n# 0 \n# 0 \nRun Code Online (Sandbox Code Playgroud)\n\n正如@Arun 在评论中指出的那样,setNames在这种情况下,“data.table”的替代方案是setattr(VALUE, \'names\', NAME),提出另一个解决方案:
dt1 <- dt[, list(list(setattr(VALUE, \'names\', NAME))), by = GROUPING]\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2881 次 |
| 最近记录: |