在R中创建一个依赖于data.table的包

时间:2015-10-09 13:11:35

标签: r data.table

我必须创建一个依赖于包 data.table 的R包。但是,如果我要执行一个功能,例如包中的下一个功能

randomdt <- function(){
    dt <- data.table(random = rnorm(10))
    dt[dt$random > 0]
}

函数 [将使用data.frame的方法而不是data.table,因此错误

Error in `[.data.frame`(x, i) : undefined columns selected

会出现。通常这可以通过使用get('[.data.table')或类似的方法来解决(package::function是最简单的),但似乎不起作用。毕竟,[是一个原始函数,我不知道它的方法是如何工作的。

那么,如何从我的包中调用data.table [函数?

1 个答案:

答案 0 :(得分:5)

根据MichaelChirico的一些反馈以及ArunSoheil的评论进行了更新。

粗略地说,您可以考虑两种方法。第一个是将依赖项构建到包本身中,而第二个是在R代码中包含用于测试data.table是否存在的行(如果找不到则会自动安装它)。

data.table FAQ在6.9中具体说明了这一点,并指出您可以通过以下方式确保data.table已正确加载:

  

要么i)在DESCRIPTION文件的Depends:字段中包含data.table,要么ii)在描述文件的Imports:字段中包含data.table并在NAMESPACE文件中包含import(data.table)。

如评论中所述,这是许多软件包中常见的R行为。

另一种方法是创建特定的代码行,以测试并导入所需的包作为代码的一部分。考虑到使用上面提供的选项的优雅,我认为这不是理想的解决方案。但是,这在技术上是可行的。

执行此操作的一种简单方法是使用requirelibrary来检查是否存在data.table,如果无法附加,则会引发错误。您甚至可以使用一组简单的条件语句来运行install.packages来安装加载它们时所需的内容。

谢永辉(编织名人)发表了一篇关于libraryrequire here之间差异的文章,并强调了在library中使用ListView myList; Button getChoice, clearAll, selectAll; SharedPreferences sharedpreferences; public static final String MyPREFERENCES = "MyUserChoice" ; ArrayList<String> selectedItems = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myList = (ListView)findViewById(android.R.id.list); getChoice = (Button)findViewById(R.id.getchoice); clearAll = (Button)findViewById(R.id.clearall); selectAll = (Button)findViewById(R.id.selectall); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice); myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); myList.setAdapter(adapter); sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE); if(sharedpreferences.contains(MyPREFERENCES)){ LoadSelections(); } getChoice.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { String selected = ""; int cntChoice = myList.getCount(); SparseBooleanArray sparseBooleanArray = myList.getCheckedItemPositions(); for (int i = 0; i < cntChoice; i++) { if (sparseBooleanArray.get(i)) { selected += myList.getItemAtPosition(i).toString() + "\n"; System.out.println("Checking list while adding:" + myList.getItemAtPosition(i).toString()); SaveSelections(); } } Toast.makeText(MainActivity.this, selected, Toast.LENGTH_LONG).show(); } }); clearAll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ClearSelections(); } }); selectAll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SelectAllSelections(); } }); packageManager = getPackageManager(); new LoadApplications().execute(); } private void SaveSelections() { // save the selections in the shared preference in private mode for the user SharedPreferences.Editor prefEditor = sharedpreferences.edit(); String savedItems = getSavedItems(); prefEditor.putString(MyPREFERENCES.toString(), savedItems); prefEditor.commit(); } private String getSavedItems() { String savedItems = ""; int count = this.myList.getAdapter().getCount(); for (int i = 0; i < count; i++) { if (this.myList.isItemChecked(i)) { if (savedItems.length() > 0) { savedItems += "," + this.myList.getItemAtPosition(i); } else { savedItems += this.myList.getItemAtPosition(i); } } } return savedItems; } private void LoadSelections() { // if the selections were previously saved load them if (sharedpreferences.contains(MyPREFERENCES.toString())) { String savedItems = sharedpreferences.getString(MyPREFERENCES.toString(), ""); selectedItems.addAll(Arrays.asList(savedItems.split(","))); int count = this.myList.getAdapter().getCount(); for (int i = 0; i < count; i++) { String currentItem = (String) myList.getAdapter() .getItem(i); if (selectedItems.contains(currentItem)) { myList.setItemChecked(i, true); Toast.makeText(getApplicationContext(), "Current Item: " + currentItem, Toast.LENGTH_LONG).show(); } else { myList.setItemChecked(i, false); } } } } private void ClearSelections() { // user has clicked clear button so uncheck all the items int count = this.myList.getAdapter().getCount(); for (int i = 0; i < count; i++) { this.myList.setItemChecked(i, false); } // also clear the saved selections SaveSelections(); } private void SelectAllSelections() { // user has clicked clear button so uncheck all the items int count = this.myList.getAdapter().getCount(); for (int i = 0; i < count; i++) { this.myList.setItemChecked(i, true); } // also clear the saved selections then uncomment the below line. // SaveSelections(); } protected void onListItemClick(ListView l, View v, int position, long id){ super.onListItemClick(l, v, position, id); ApplicationInfo app = applist.get(position); try{ Intent intent = packageManager.getLaunchIntentForPackage(app.packageName); /*if(intent != null){ startActivity(intent); }*/ }catch(ActivityNotFoundException e){ Toast.makeText(MainActivity.this,e.getMessage(), Toast.LENGTH_LONG).show(); }catch(Exception e){ Toast.makeText(MainActivity.this,e.getMessage(), Toast.LENGTH_LONG).show(); } } private List<ApplicationInfo> checkForLaunchIntent(List<ApplicationInfo> list){ ArrayList<ApplicationInfo> appList = new ArrayList<ApplicationInfo>(); for(ApplicationInfo info : list){ try{ if(packageManager.getLaunchIntentForPackage(info.packageName)!=null){ appList.add(info); } }catch(Exception e){ e.printStackTrace(); } } return appList; } private class LoadApplications extends AsyncTask<Void, Void, Void>{ private ProgressDialog progress = null; protected Void doInBackground(Void... params){ applist = checkForLaunchIntent(packageManager.getInstalledApplications(PackageManager.GET_META_DATA)); listadapter = new AppAdapter(MainActivity.this, R.layout.activity_list_app, applist); return null; } protected void onPostExecute(Void result){ setListAdapter(listadapter); progress.dismiss(); super.onPostExecute(result); } protected void onPreExecute(){ progress = ProgressDialog.show(MainActivity.this, null, "Loading apps info..."); super.onPreExecute(); } } } 的情况该软件包对于即将推出的代码绝对必不可少。