R、 data.table-为多个表创建新列

R、 data.table-为多个表创建新列,r,data.table,apply,lapply,R,Data.table,Apply,Lapply,假设我有两个表,它们的名称是: csvs <- c("jan", "feb") 是的,我更喜欢应用而不是循环。但是,我收到以下错误: 检测到无效的.internal.selfref,并通过获取data.table的(浅层)副本进行修复,以便:=可以通过引用添加此新列。在此之前,此data.table已被R复制(或使用structure()或类似工具手动创建)。避免使用姓名T.Fung, 如果您希望向每个名为的数据帧添加一列,比如说period,该列

假设我有两个表,它们的名称是:

csvs <- c("jan", "feb")
是的,我更喜欢应用而不是循环。但是,我收到以下错误:

检测到无效的.internal.selfref,并通过获取data.table的(浅层)副本进行修复,以便:=可以通过引用添加此新列。在此之前,此data.table已被R复制(或使用structure()或类似工具手动创建)。避免使用姓名T.Fung, 如果您希望向每个名为的数据帧添加一列,比如说
period
,该列中的值都是数据帧的名称,您可以这样做:

jan$'period' <- 'jan'
feb$'period' <- 'feb'
1月$'period'1月5日
下面介绍了如何使用apply函数执行此操作:

# some example data
jan <- data.frame('some_data' = seq(1:5), 'more_data' = seq(6:10))
feb <- data.frame('some_data' = seq(1:5), 'more_data' = seq(6:10))

# vector of your table names
csvs <- c('jan', 'feb')

# This will put all the dataframes into a list
my_fun <- function(csvs){
  tmp <- paste0(csvs,'$period <- \'', csvs, '\'',sep = "")
  eval(parse(text = tmp))
  df <- eval(parse(text=csvs))
  return(df)
}

# apply the function and create a list of dataframes
dfs <- lapply(csvs, FUN = my_fun)

# name the dataframes in the list
names(dfs) <- csvs

# pull the dataframes out of the list and assign to the environment
lapply(names(dfs), function(x) assign(x, dfs[[x]], envir = .GlobalEnv))
#> [[1]]
#>   some_data more_data period
#> 1         1         1    jan
#> 2         2         2    jan
#> 3         3         3    jan
#> 4         4         4    jan
#> 5         5         5    jan
#> 
#> [[2]]
#>   some_data more_data period
#> 1         1         1    feb
#> 2         2         2    feb
#> 3         3         3    feb
#> 4         4         4    feb
#> 5         5         5    feb

# check dataframes for period column
jan
#>   some_data more_data period
#> 1         1         1    jan
#> 2         2         2    jan
#> 3         3         3    jan
#> 4         4         4    jan
#> 5         5         5    jan
feb
#>   some_data more_data period
#> 1         1         1    feb
#> 2         2         2    feb
#> 3         3         3    feb
#> 4         4         4    feb
#> 5         5         5    feb
#一些示例数据
简
#> [[2]]
#>一些\u数据更多\u数据周期
#>2月1日
#>2月2日
#>2月3日
#>2月4日
#>2月5日
#检查周期列的数据帧
简
#>一些\u数据更多\u数据周期
#>1月1日
#>1月2日
#>1月3日
#>1月4日
#>1月5日
2月
#>一些\u数据更多\u数据周期
#>2月1日
#>2月2日
#>2月3日
#>2月4日
#>2月5日
T.Fung, 如果您希望向每个名为的数据帧添加一列,比如说
period
,该列中的值都是数据帧的名称,您可以这样做:

jan$'period' <- 'jan'
feb$'period' <- 'feb'
1月$'period'1月5日
下面介绍了如何使用apply函数执行此操作:

# some example data
jan <- data.frame('some_data' = seq(1:5), 'more_data' = seq(6:10))
feb <- data.frame('some_data' = seq(1:5), 'more_data' = seq(6:10))

# vector of your table names
csvs <- c('jan', 'feb')

# This will put all the dataframes into a list
my_fun <- function(csvs){
  tmp <- paste0(csvs,'$period <- \'', csvs, '\'',sep = "")
  eval(parse(text = tmp))
  df <- eval(parse(text=csvs))
  return(df)
}

# apply the function and create a list of dataframes
dfs <- lapply(csvs, FUN = my_fun)

# name the dataframes in the list
names(dfs) <- csvs

# pull the dataframes out of the list and assign to the environment
lapply(names(dfs), function(x) assign(x, dfs[[x]], envir = .GlobalEnv))
#> [[1]]
#>   some_data more_data period
#> 1         1         1    jan
#> 2         2         2    jan
#> 3         3         3    jan
#> 4         4         4    jan
#> 5         5         5    jan
#> 
#> [[2]]
#>   some_data more_data period
#> 1         1         1    feb
#> 2         2         2    feb
#> 3         3         3    feb
#> 4         4         4    feb
#> 5         5         5    feb

# check dataframes for period column
jan
#>   some_data more_data period
#> 1         1         1    jan
#> 2         2         2    jan
#> 3         3         3    jan
#> 4         4         4    jan
#> 5         5         5    jan
feb
#>   some_data more_data period
#> 1         1         1    feb
#> 2         2         2    feb
#> 3         3         3    feb
#> 4         4         4    feb
#> 5         5         5    feb
#一些示例数据
简
#> [[2]]
#>一些\u数据更多\u数据周期
#>2月1日
#>2月2日
#>2月3日
#>2月4日
#>2月5日
#检查周期列的数据帧
简
#>一些\u数据更多\u数据周期
#>1月1日
#>1月2日
#>1月3日
#>1月4日
#>1月5日
2月
#>一些\u数据更多\u数据周期
#>2月1日
#>2月2日
#>2月3日
#>2月4日
#>2月5日

如果我只是将
eval(as.name(x))
替换为
get(x)
(参见下面的示例),您的
lapply
解决方案对我来说可以很好地处理数据。表1.13.6

test1 <- data.table(a = 1:3, b = 4:6)
test2 <- data.table(a = 7:9, b = 10:12)
dtNames <- c("test1", "test2")

lapply(dtNames, function(x) get(x)[, dtName := x])

test1如果我只是将
eval(as.name(x))
替换为
get(x)
(参见下面的示例),您的
lapply
解决方案对我来说可以很好地处理数据。表1.13.6

test1 <- data.table(a = 1:3, b = 4:6)
test2 <- data.table(a = 7:9, b = 10:12)
dtNames <- c("test1", "test2")

lapply(dtNames, function(x) get(x)[, dtName := x])


test1 T.Fung,您的目标是在“jan”数据框中有一列“jan”,在“feb”数据框中有一列“feb”吗?没错,C Jeruzal如果您将
eval(as.name(x))
替换为
get(x)
,这只是一个问题,您仍然会遇到相同的错误吗?刚刚在使用旧R和data.table版本的计算机上尝试了您的解决方案,但仍然运行。所以一定和我的实际情况有关dataset@T.Fung从错误消息判断,它很可能与数据的导入方式有关,或者您可能在之前对数据进行了一些操作;如果可能的话,可以用更多的信息更新你的问题(数据的一个例子或子集),并展示它是如何导入的?T.Fung,你的目标是在“一月”数据框中有一列“一月”,在“二月”数据框中有一列“二月”吗?没错,C Jeruzal只是一个问题,如果你用
get(x)替换
eval(as.name(x))
,您仍然会遇到相同的错误吗?刚刚在使用旧R和data.table版本的计算机上尝试了您的解决方案,但仍然运行。所以一定和我的实际情况有关dataset@T.Fung从错误消息判断,它很可能与数据的导入方式有关,或者您可能在之前对数据进行了一些操作;如果可能的话,可以用更多的信息更新你的问题(数据的一个例子或子集),并显示它是如何导入的?是的。非常感谢。但是我正在寻找一个apply函数,因为我有大量的dataframesT。冯,我为你添加了一个循环。非常感谢你的想法,@C Jeruzal。然而,正如我在最初的帖子中提到的,我正在寻找一个应用函数。冯,我添加了一个应用选项供您查看。首先,它将所有数据帧放在一个列表变量中,然后将每个数据帧作为一个数据帧变量取出。将我们需要的内容存储在一个列表中,然后在全局环境中重新分配回dfs。对我来说是一种全新的方法。这远不是最优雅的方法,但我可以选择一种供将来使用的方法。谢谢,真的。非常感谢。但是我正在寻找一个apply函数,因为我有大量的dataframesT。冯,我为你添加了一个循环。非常感谢你的想法,@C Jeruzal。然而,正如我在最初的帖子中提到的,我正在寻找一个应用函数。冯,我添加了一个应用选项供您查看。首先,它将所有数据帧放在一个列表变量中,然后将每个数据帧作为一个数据帧变量取出。将我们需要的内容存储在一个列表中,然后在全局环境中重新分配回dfs。对我来说是一种全新的方法。这远不是最优雅的方法,但我可以选择一种供将来使用的方法。谢谢。我通过简单地将它分配给一个对象来“解决”它,因此,输出对象是一个列表x@T.Fung至少它是一个警告,而不是一个错误我通过简单地将它分配给一个对象来“解决”它,因此,输出对象是一个列表x@T.Fung至少它是一个警告,而不是一个错误