【问题标题】:R - For Loop through Rows of Dataframe + Write Long Text to FileR - For循环遍历数据框行+将长文本写入文件
【发布时间】:2020-04-14 19:04:30
【问题描述】:

我正在为 R 中的一个特定 for 循环而苦苦挣扎。我有一个包含 52 行和大约 30 列的数据框。我正在编写 for 循环以从每一行中提取数据(或值)并将它们插入到长文本中——在本例中为 javascript/geojson 代码。目前,length() 不接受我放入其中的任何参数。

我是 R 新手,所以很多代码可能是多余的。

代码如下:

# start of 'for loop' 
for(row in 1:nrow(intro_df)) { # trying to iterate through each row of the df
  lines <- vector(length()) # trying to deal with getting an error for "replacement has length zero" 
  # start of long text (notice placeholders in sprintf) --- javascript/geojson to be used in VS code later
  lines[row] <- sprintf(" 
{
            \"type\": \"Feature\",
            \"properties\": {
                \"huc8\": %s,
                \"Year\": %i,
                \"Total Water Use\": %f,
                \"Aquaculture\": %f,
                \"Commercial\": %f,
                \"Self-Supplied Domestic\": %f,
                \"Hydroelectric Power\": %f,
                \"Self-Supplied Industrial\": %f,
                \"Irrigation\": %f,
                \"Livestock\": %f,
                \"Mining\": %f,
                \"Public Supply\": %f,
                \"Thermoelectric\": %f,
                \"Total Groundwater\": %f,
                \"Total Surface Water\": %f
            },
            \"geometry\": {
                \"type\": \"Point\",
                \"coordinates\": [%f, %f]
            }
        }, \n", 
  intro_df$huc8[row], # column names where data/values from intro_df should be inserted into sprintf
  intro_df$Year[row], 
  intro_df$Total_WaterUse[row], 
  intro_df$Aquaculture[row], 
  intro_df$Commercial[row], 
  intro_df$Domestic[row], 
  intro_df$Hydroelectric_power[row], 
  intro_df$Industrial[row], 
  intro_df$Irrigation[row], 
  intro_df$Livestock[row], 
  intro_df$Mining[row], 
  intro_df$Public_Supply[row], 
  intro_df$Thermoelectric[row], 
  intro_df$Total_Groundwater[row], 
  intro_df$Total_Surface_Water[row], 
  intro_df$lat[row], 
  intro_df$long[row])

}
all_lines <- paste(lines, collapse = "\n") # store lines to variable all_lines

file_js_points <- file("js_points.txt") # write all_lines to a text file 
writeLines(all_lines, file_js_points)
close(file_js_points)

编辑我更正了我的代码以摆脱“for循环”。以下是最终为我工作的代码:

# Input data from each row of intro_df into placeholders in sprintf()
lines <- sprintf(" 
{ 
            \"type\": \"Feature\",
            \"properties\": {
                \"huc8\": %s, 
                \"Year\": %s,
                \"Total Water Use\": %s,
                \"Aquaculture\": %s,
                \"Commercial\": %s, 
                \"Self-Supplied Domestic\": %s,
                \"Hydroelectric Power\": %s,
                \"Self-Supplied Industrial\": %s,
                \"Irrigation\": %s, 
                \"Livestock\": %s, 
                \"Mining\": %s, 
                \"Public Supply\": %s, 
                \"Thermoelectric\": %s, 
                \"Total Groundwater\": %s, 
                \"Total Surface Water\": %s 
            }, 
            \"geometry\": { 
                \"type\": \"Point\", 
                \"coordinates\": [%s, %s] 
            } 
        }, \n", 
                      intro_df$huc8, # column names where data/values from intro_df should be inserted into sprintf
                      intro_df$Year, 
                      intro_df$Total_WaterUse, 
                      intro_df$Aquaculture, 
                      intro_df$Commercial, 
                      intro_df$Domestic, 
                      intro_df$Hydroelectric_power, 
                      intro_df$Industrial, 
                      intro_df$Irrigation, 
                      intro_df$Livestock, 
                      intro_df$Mining, 
                      intro_df$Public_Supply, 
                      intro_df$Thermoelectric, 
                      intro_df$Total_Groundwater, 
                      intro_df$Total_Surface_Water, 
                      intro_df$lat, 
                      intro_df$long)

# Collapse all rows into one variable separated by new line 
js_points <- paste(lines, collapse = "\n") 

# Create js_point text file for all js_points
sink(file = "js_points.txt")
cat(js_points)
sink()

【问题讨论】:

  • 如果您将数据样本(使用dput())添加到make your example reproducible 以便其他人可以运行您的代码,您更有可能获得帮助。

标签: r for-loop asprintf


【解决方案1】:

问题是您在每次循环迭代开始时将lines 重置为空。您应该在循环之前 初始化它(最好是正确的长度,而不是 0 长度)。您需要使用 参数 length = 而不是函数 length()。 (我也使用character,所以它是正确的向量类型。)

lines = character(length = nrow(intro_df))
for(row in 1:nrow(intro_df)) { 
  lines[row] <- ...
}

但是sprintf 是矢量化的,因此您根本不需要 for 循环。我使用with() 来避免多次输入数据框名称。

lines <- with(intro_df, sprintf("
  {...

  }",
  huc8,
  Year,
  Total_WaterUse, ...
))

all_lines <- paste(lines, collapse = "\n") # store lines to variable all_lines

file_js_points <- file("js_points.txt") # write all_lines to a text file 
writeLines(all_lines, file_js_points)
close(file_js_points)

【讨论】:

  • 是的!我最终摆脱了 for 循环,效果更好。让我看看我是否可以分享有用的代码。
猜你喜欢
  • 1970-01-01
  • 2022-01-20
  • 2023-03-20
  • 2011-06-19
  • 2016-05-07
  • 2018-12-31
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
相关资源
最近更新 更多