R 根据存储在列中的值创建新行

R 根据存储在列中的值创建新行,r,data.table,R,Data.table,我有以下数据 structure(list(State = c(56L, 81L, 126L, 161L, 120L, 138L, 71L, 133L, 6L, 171L, 42L, 64L, 28L, 76L, 56L, 117L, 47L, 69L, 65L, 105L, 175L, 151L, 0L, 91L, 150L, 157L, 172L, 69L, 132L, 39L, 152L, 107L, 142L, 174L, 187L, 84L, 58L, 73L, 198L, 5L

我有以下数据

structure(list(State = c(56L, 81L, 126L, 161L, 120L, 138L, 71L, 
133L, 6L, 171L, 42L, 64L, 28L, 76L, 56L, 117L, 47L, 69L, 65L, 
105L, 175L, 151L, 0L, 91L, 150L, 157L, 172L, 69L, 132L, 39L, 
152L, 107L, 142L, 174L, 187L, 84L, 58L, 73L, 198L, 5L, 43L, 189L, 
34L, 177L, 119L, 69L, 152L, 155L, 44L, 59L, 20L, 120L, 1L, 173L, 
190L, 121L, 118L, 168L, 80L, 45L, 26L, 15L, 190L, 25L, 7L, 146L, 
177L, 41L, 28L, 190L, 64L, 76L, 194L, 13L, 172L, 120L, 132L, 
160L, 58L, 12L), AgentID = 1:80, t_IDs = c("1 15", "2", "3", 
"4", "5 52 76", "6", "7", "8", "9", "10", "11", "12 71", "13 69", 
"14 72", "1 15", "16", "17", "18 28 46", "19", "20", "21", "22", 
"23", "24", "25", "26", "27 75", "18 28 46", "29 77", "30", "31 47", 
"32", "33", "34", "35", "36", "37 79", "38", "39", "40", "41", 
"42", "43", "44 67", "45", "18 28 46", "31 47", "48", "49", "50", 
"51", "5 52 76", "53", "54", "55 63 70", "56", "57", "58", "59", 
"60", "61", "62", "55 63 70", "64", "65", "66", "44 67", "68", 
"13 69", "55 63 70", "12 71", "14 72", "73", "74", "27 75", "5 52 76", 
"29 77", "78", "37 79", "80")), row.names = c(NA, -80L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x560df68bf760>)

使用您提供的3列数据,我执行了以下操作:

n = matrix(ncol= 3)[-1,]
for(i in grep(' ', df$t_IDs)){
  b = df[i,]
  c = length(gregexpr(' ',as.character(b[,3]))[[1]])+1
  d = b[rep(1,c),1:2]
  d$t_IDs = as.numeric(unlist(strsplit(as.character(b[1,3]), ' ')))
  n = rbind(n,as.matrix(d))
  }
df_new = df[-grep(' ', df$t_IDs),]
df_new = rbind(df_new, n)
df_new= df_new[order(df_new$AgentID),]
它给出了这个结果

     State AgentID t_IDs
  1:    56       1     1
  2:    56       1    15
  3:    81       2     2
  4:   126       3     3
  5:   161       4     4
 ---                    
112:   132      77    77
113:   160      78    78
114:    58      79    37
115:    58      79    79
116:    12      80    80

我希望使用您提供的3列数据能有所帮助,我执行了以下操作:

n = matrix(ncol= 3)[-1,]
for(i in grep(' ', df$t_IDs)){
  b = df[i,]
  c = length(gregexpr(' ',as.character(b[,3]))[[1]])+1
  d = b[rep(1,c),1:2]
  d$t_IDs = as.numeric(unlist(strsplit(as.character(b[1,3]), ' ')))
  n = rbind(n,as.matrix(d))
  }
df_new = df[-grep(' ', df$t_IDs),]
df_new = rbind(df_new, n)
df_new= df_new[order(df_new$AgentID),]
它给出了这个结果

     State AgentID t_IDs
  1:    56       1     1
  2:    56       1    15
  3:    81       2     2
  4:   126       3     3
  5:   161       4     4
 ---                    
112:   132      77    77
113:   160      78    78
114:    58      79    37
115:    58      79    79
116:    12      80    80
我希望这会有所帮助,我会尝试使用data.table。使用strsplit按空格分隔t_id中的值,使用unlist将为新的t_id列提供一个长向量。这是针对每个状态和AgentID组合执行的

library(data.table)

setDT(dt)

dt[, list(t_IDs = unlist(strsplit(t_IDs, " "))), by = c("State", "AgentID")]
不假定状态/代理唯一性的替代方案可能是:

dt[ ,.(State, AgentID, new_tIDs = unlist(strsplit(t_IDs, " "))), by = seq_len(nrow(dt))]
输出

我会尝试使用data.table。使用strsplit按空格分隔t_id中的值,使用unlist将为新的t_id列提供一个长向量。这是针对每个状态和AgentID组合执行的

library(data.table)

setDT(dt)

dt[, list(t_IDs = unlist(strsplit(t_IDs, " "))), by = c("State", "AgentID")]
不假定状态/代理唯一性的替代方案可能是:

dt[ ,.(State, AgentID, new_tIDs = unlist(strsplit(t_IDs, " "))), by = seq_len(nrow(dt))]
输出

如果不能保证状态/代理对是唯一的,一种方法是使用行方式取消列出:

DT[,.State=State[1],AgentID=AgentID[1],t_id=unlistrsplitt_id,split=,by=seq_lennrowDT][,-1] 国家机构 1: 56 1 1 2: 56 1 15 3: 81 2 2 4: 126 3 3 5: 161 4 4 6: 120 5 5 7: 120 5 52 8: 120 5 76 9: 138 6 6 10: 71 7 7 - 107: 172 75 75 108: 120 76 5 109: 120 76 52 110: 120 76 76 111: 132 77 29 112: 132 77 77 113: 160 78 78 114: 58 79 37 115: 58 79 79 116: 12 80 80 或者,我们可以使用列表列,然后使用tidyr::unnest将其分解:

tidyr::unnestDT[,t_id:=strsplitt_id,split=][],t_id A tibble:116 x 3 国家机构 1 56 1 1 2 56 1 15 3 81 2 2 4 126 3 3 5 161 4 4 6 120 5 5 7 120 5 52 8 120 5 76 9 138 6 6 10 71 7 7 ... 还有106行 这会产生转换为tbl_df的副作用。

如果不能保证状态/代理对是唯一的,一种方法是使用逐行取消列表:

DT[,.State=State[1],AgentID=AgentID[1],t_id=unlistrsplitt_id,split=,by=seq_lennrowDT][,-1] 国家机构 1: 56 1 1 2: 56 1 15 3: 81 2 2 4: 126 3 3 5: 161 4 4 6: 120 5 5 7: 120 5 52 8: 120 5 76 9: 138 6 6 10: 71 7 7 - 107: 172 75 75 108: 120 76 5 109: 120 76 52 110: 120 76 76 111: 132 77 29 112: 132 77 77 113: 160 78 78 114: 58 79 37 115: 58 79 79 116: 12 80 80 或者,我们可以使用列表列,然后使用tidyr::unnest将其分解:

tidyr::unnestDT[,t_id:=strsplitt_id,split=][],t_id A tibble:116 x 3 国家机构 1 56 1 1 2 56 1 15 3 81 2 2 4 126 3 3 5 161 4 4 6 120 5 5 7 120 5 52 8 120 5 76 9 138 6 6 10 71 7 7 ... 还有106行
这会产生转换为tbl_df的副作用。

这在tidyr一步解决方案中非常容易做到

separate_rows(dt, t_IDs, sep = ' ')

# A tibble: 116 x 3
   State AgentID t_IDs
   <int>   <int> <chr>
 1    56       1 1    
 2    56       1 15   
 3    81       2 2    
 4   126       3 3    
 5   161       4 4    
 6   120       5 5    
 7   120       5 52   
 8   120       5 76   
 9   138       6 6    
10    71       7 7    
# ... with 106 more rows

这在tidyr一步解决方案中非常容易做到

separate_rows(dt, t_IDs, sep = ' ')

# A tibble: 116 x 3
   State AgentID t_IDs
   <int>   <int> <chr>
 1    56       1 1    
 2    56       1 15   
 3    81       2 2    
 4   126       3 3    
 5   161       4 4    
 6   120       5 5    
 7   120       5 52   
 8   120       5 76   
 9   138       6 6    
10    71       7 7    
# ... with 106 more rows

非常感谢你的回答,但是你能解释一下你在做什么吗?当然!基本上,我查找了df$t_id包含“”空间的所有行,这意味着这一行中有多个值,然后我将这些行复制到t_id中的元素数,并用分离的t_id绑定它们。我对所有需要复制的行执行此操作,然后用我创建的n对象替换用grep标识的旧行,并对所有行重新排序。简要说明:选择具有多个值的行->复制这些行并将其绑定到n对象->删除旧行df[-grep…,]->换成新的谢谢你的回答,但是你能解释一下你在做什么吗?当然!基本上,我查找了df$t_id包含“”空间的所有行,这意味着这一行中有多个值,然后我将这些行复制到t_id中的元素数,并用分离的t_id绑定它们。我对需要复制的所有行执行此操作,然后将用grep标识的旧行替换为我已创建的n对象,并对所有行重新排序简要说明:选择具有多个值的行->复制这些行并将它们绑定到
n对象->删除旧行df[-grep…,]->替换为新行如果State+AgentID不都是唯一的,那么这可能会失败。非常感谢Ben。有没有办法通过:=?因为现在t_id是暂时的variable@r2evans正确,我同意,这假设了国家/机构的唯一性。我将添加一个没有这个假设的替代解决方案…不,我的意思是我不想创建一个新的数据表。我只是想使用数据表。我使用的实际数据集是巨大的。如果State+AgentID不都是唯一的,则可能会失败。非常感谢Ben。有没有办法通过:=?因为现在t_id是暂时的variable@r2evans正确,我同意,这假设了国家/机构的唯一性。我将添加一个没有这个假设的替代解决方案…不,我的意思是我不想创建一个新的数据表。我只想使用data.table我使用的实际数据集是huge当执行赋值t_IDs=unlist时,有没有办法直接赋值:=?为什么这么重要?因为我有一个巨大的数据集,不想每次都复制数据当你选择将一个分隔字段拆分为多行时,你会丢失大部分数据?data.table的引用语义。在就地操作中,无法将1个t_ID单元格替换为3个t_ID单元格。在执行赋值t_ID=unlist时,是否有方法直接赋值为:=?为什么这么重要?因为我有一个巨大的数据集,不想每次都复制数据当您选择将分隔字段拆分为多行时,你失去了一切?data.table的引用语义。在就地操作中,无法用三个t_ID单元替换一个t_ID单元。非常感谢![一些角色]非常感谢![一些字符]