我在hadley的功能指南中经历了一些例子,并遇到了意想不到的问题.
假设我有一个模型对象列表,
x=1:3;y=3:1; bah <- list(lm(x~y),lm(y~x))
Run Code Online (Sandbox Code Playgroud)
并希望从每个中提取一些东西(如hadley关于名为"试验"的列表的问题所示).我期待其中一个工作:
lapply(bah,`$`,i='call') # or...
lapply(bah,`$`,call)
Run Code Online (Sandbox Code Playgroud)
但是,这些返回null.好像我没有滥用这个$功能,因为这些东西有效:
`$`(bah[[1]],i='call')
`$`(bah[[1]],call)
Run Code Online (Sandbox Code Playgroud)
无论如何,我只是把它作为一个练习,我很好奇我的错误.我知道我可以使用匿名函数,但认为必须有一种方法来使用类似于我最初的非解决方案的语法.我已经看过了$所提到的地方?Extract,但没有看到任何明显的解释.
我才意识到这有效:
lapply(bah,`[[`,i='call')
Run Code Online (Sandbox Code Playgroud)
还有这个
lapply(bah,function(x)`$`(x,call))
Run Code Online (Sandbox Code Playgroud)
也许这只是归结为一些lapply需要匿名功能而不需要任何功能的伏都教?我觉得我以前在某个地方听说过.
注意:我在此问题中遇到的确切问题不适用于最新版本的数据表.如果你想做标题中描述的事情,请查看包FAQ中的相应问题,1.6确定,但我不提前知道这些表达式.我如何以编程方式传递它们?.
我已经看到一个答案,说明如何构建一个要进行评估的表达式
DT[,j=eval(expr)]
Run Code Online (Sandbox Code Playgroud)
我正在使用这个作业,```:=`(mycol = my_calculation)``,我想知道......
通过"动态",我的意思是"在我为我编写代码后确定expr".
编辑:为了更好地说明问题,这里是不同的例子.查看编辑历史记录以查看原始文件.
require(data.table)
require(plyr)
options(datatable.verbose=TRUE)
DT <- CJ(a=0:1,b=0:1,y=2)
# setup:
expr <- as.quoted(paste(expression(get(col_in_one)+get(col_in_two))))[[1]]
# usage:
col_in_one <- 'a'
col_in_two <- 'b'
col_out <- 'bah'
DT[,(col_out):=eval(expr)] # fails, should take the form j=eval(expr)
Run Code Online (Sandbox Code Playgroud)
我想将设置和使用阶段分开,因此我的代码更易于维护.我的真实表达比这个例子更麻烦(它只选择一列).
第一个问题:如何使分配到的列"col_out"动态化?我的意思是:我想动态指定"cols_in_*"和"col_out".
我尝试在"expr"中创建各种表达式,但as.quoted抛出一个错误,即不将某些东西放在=符号的左边.
第二个问题:如何避免使用警告
get?
警告建议使用.SDcols,以便[.data.table知道我正在使用哪些列.但是,如果我使用这个.SDcols参数,另一个警告说除非.SD正在使用,否则没有必要这样做.
我到目前为止的解决方案是......
# Ricardo + eddi:
expr2 …Run Code Online (Sandbox Code Playgroud) 我试图将我的数据框分成2个部分.例如,我想将70%的数据随机存入一个数据帧,另外30%的数据存入其他数据帧.有没有快速的方法来做到这一点?原始数据框中的行数超过800000.我尝试使用for循环,从行数中选择一个随机数,然后使用rbind()将该行绑定到第一个(70%)数据框并从原始数据帧中删除它以获得另一个(30%)数据帧.但这非常缓慢.有没有比这更快的方法呢?
不确定如何用单词表达问题,但是如何为data.table创建一个索引列,当出现不同的值时,每个组会增加?
这是MWE
library(data.table)
in.data <- data.table(fruits=c(rep("banana", 4), rep("pear", 5)),vendor=c("a", "b", "b", "c", "d", "d", "e", "f", "f"))
Run Code Online (Sandbox Code Playgroud)
这是R代码应该生成的结果
in.data[, wanted.column:=c(1,2,2,3,1,1,2,3,3)]
# fruits vendor wanted.column
# 1: banana a 1
# 2: banana b 2
# 3: banana b 2
# 4: banana c 3
# 5: pear d 1
# 6: pear d 1
# 7: pear e 2
# 8: pear f 3
# 9: pear f 3
Run Code Online (Sandbox Code Playgroud)
因此它在每个水果中标记每个供应商1,2,3,.... 可能有一个非常简单的解决方案,但我被卡住了.
我编写了以下两个函数,一个用于使用连接测试增加的向量大小,另一个用括号测试:
c_test <- function(n) {
cv = c()
for(i in 1:n) cv = c(cv, i)
cv
}
b_test <- function(n) {
bv = c()
for (i in 1:n) bv[i] = i
bv
}
library(microbenchmark)
microbenchmark(c_test(1e+4), b_test(1e+4), times = 100)
#Unit: milliseconds
# expr min lq mean median uq max neval
# c_test(10000) 140.27923 145.73282 156.82319 148.16175 151.74713 267.2393 100
# b_test(10000) 49.58033 54.42992 56.24268 54.86033 56.30862 132.8394 100
Run Code Online (Sandbox Code Playgroud)
这是一个很大的时间差异,我不明白为什么使用括号比使用连接更好.在这两种情况下似乎都需要时间来分配新的内存,但这似乎并不正确.我还认为它可能会c(v, x)转换x为与v合并之前相同的类型,但是说v[i] = as.vector(x)并不是一个重要的时间成本.
当我filter()或者select()具有空格的列名称通常在dplyr中使用反引号定义时,我的内联代码块会中断.
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(dplyr)
library(knitr)
library(lazyeval)
df <- structure(list(1:3, 2:4), .Names = c("a", "b"), row.names = c(NA, -3L), class = "data.frame")
df <- df %>% select(`a a`=a, `b b`=b)
```
Run Code Online (Sandbox Code Playgroud)
我正在尝试类似的东西`r df %>% filter(`a a` == 1) %>% select(`a a`) %>% as.numeric()`,但是我收到以下错误:
Error in base::parse(text = code, keep.source = FALSE) : <text>:2.0: unexpected end of input 1: df %>% filter( ^ Calls: <Anonymous> ... inline_exec -> withVisible …Run Code Online (Sandbox Code Playgroud) 这对我来说很难解释,因此我仅举一个例子。我在下面有两个向量(a和b)。
a <- c("cat","dog","banana","yogurt","dog")
b <- c("salamander","worm","dog","banana","cat","yellow","blue")
Run Code Online (Sandbox Code Playgroud)
我想要以下结果:
[1] 0 0 2 1 1 0 0
Run Code Online (Sandbox Code Playgroud)
其中结果的每个元素是b的每个元素出现在向量a中的次数。
do.call("c",lapply(b,function(x){sum(x == a)}))
Run Code Online (Sandbox Code Playgroud)
这给了我我想要的,但是我需要一个矢量化/更快的版本,因为我正在处理> 20,000条记录。任何帮助表示赞赏!
我正在尝试计算我的数据框中的几个新变量.以初始值为例:
说我有:
Dataset <- data.frame(time=rep(c(1990:1992),2),
geo=c(rep("AT",3),rep("DE",3)),var1=c(1:6), var2=c(7:12))
time geo var1 var2
1 1990 AT 1 7
2 1991 AT 2 8
3 1992 AT 3 9
4 1990 DE 4 10
5 1991 DE 5 11
6 1992 DE 6 12
Run Code Online (Sandbox Code Playgroud)
而且我要:
time geo var1 var2 var1_1990 var1_1991 var2_1990 var2_1991
1 1990 AT 1 7 1 2 7 8
2 1991 AT 2 8 1 2 7 8
3 1992 AT 3 9 1 2 7 8
4 1990 DE …Run Code Online (Sandbox Code Playgroud) 我试图找到一种更有效的方法来逐步计算数据帧中的唯一数据点.
例如,我编写了以下代码:
df = matrix(c(1,2,3,3,4,5,1,2,4,4))
count = matrix(nrow = nrow(df),ncol=1)
for (i in 1:nrow(df)) {
count[i,1] = length(which(df[1:i,1] == df[i,1]))
}
Run Code Online (Sandbox Code Playgroud)
代码的目的是逐步计算特定值的每个实例,例如count列将具有以下结果:
1,1,1,2,1,1,2,2,2,3.
Run Code Online (Sandbox Code Playgroud)
到目前为止我编写的代码完成了这项工作,但上面的示例df只包含10个值.我试图执行此功能的实际数据框包含52,118 values,这需要花费大量时间.
有谁知道一种更有效的方法来执行上面的代码?
我有两个数据帧,第一个包含9994行,第二个包含60431行.我想合并两个数据帧,使合并的数据帧包含两个数据帧的组合列,但只包含9994行.
但是,合并后我获得超过9994行.我怎样才能确保不会发生这种情况?
df1 = readRDS('data1.RDS')
nrow(df1)
# [1] 9994
df2 = readRDS('data2.RDS')
nrow(df2)
# [1] 60431
df = merge(df1,df2,by=c("col1","col2"))
nrow(df)
# [1] 10057
df = merge(df1,df2,by=c("col1","col2"),all.x=TRUE)
nrow(df)
# [1] 10057
nrow(na.omit(df))
# [1] 10057
Run Code Online (Sandbox Code Playgroud)
编辑:遵循akrun的评论.是的,第二个数据框中有重复项
nrow(unique(df2[,c("col1","col2")]))
# [1] 60263
nrow(df2)
# [1] 60431
Run Code Online (Sandbox Code Playgroud)
如果同一{col1,col2}组合有多个,如何从数据框中只取一行.当我合并时,我想只有9994行.
r ×10
dataframe ×3
data.table ×2
lapply ×2
backticks ×1
count ×1
dplyr ×1
inline-code ×1
merge ×1
r-markdown ×1
random ×1
rstudio ×1
split ×1